2016-02-04 197 views
1

我在Ubuntu 14.04 LTS機器上運行生產時有一個Node.js應用程序服務器,但是當我嘗試通過瀏覽器進行連接時,PM2日誌中顯示以下錯誤:Error EACCES權限被拒絕mkdir multer node.js

www-0 (err): Error: EACCES: permission denied, mkdir '/var/www/myapp/MyApp/MyApp/uploads' 
www-0 (err):  at Error (native) 
www-0 (err):  at Object.fs.mkdirSync (fs.js:794:18) 
www-0 (err):  at Function.sync (/var/www/myapp/MyApp/MyApp/node_modules/multer/node_modules/mkdirp/index.js:71:13) 
www-0 (err):  at new DiskStorage (/var/www/myapp/MyApp/MyApp/node_modules/multer/storage/disk.js:21:12) 
www-0 (err):  at module.exports (/var/www/myapp/MyApp/MyApp/node_modules/multer/storage/disk.js:65:10) 
www-0 (err):  at new Multer (/var/www/myapp/MyApp/MyApp/node_modules/multer/index.js:15:20) 
www-0 (err):  at multer (/var/www/myapp/MyApp/MyApp/node_modules/multer/index.js:88:12) 
www-0 (err):  at Object.<anonymous> (/var/www/myapp/MyApp/MyApp/app.js:45:9) 
www-0 (err):  at Module._compile (module.js:410:26) 
www-0 (err):  at Object.Module._extensions..js (module.js:417:10) 
www-0 (err):  at Module.load (module.js:344:32) 
www-0 (err):  at Function.Module._load (module.js:301:12) 
www-0 (err):  at Function._load (/usr/local/lib/node_modules/pm2/node_modules/pmx/lib/transaction.js:62:21) 
www-0 (err):  at Module.require (module.js:354:17) 
www-0 (err):  at require (internal/module.js:12:17) 
www-0 (err):  at Object.<anonymous> (/var/www/myapp/MyApp/MyApp/bin/www:7:11) 

正如你所看到的,誤差來源於multer包。我目前使用multer 1.1.0版本,這是我app.js文件:

// app.js 

// set up ====================================================================== 
// get all the tools we need 

var express = require('express'); 
var path = require('path'); 
var favicon = require('serve-favicon'); 
var logger = require('morgan'); 
var cookieParser = require('cookie-parser'); 
var bodyParser = require('body-parser'); 
var session = require('express-session'); 
var mongoose = require('mongoose'); 
var passport = require('passport'); 
var flash = require('connect-flash'); 
var multer = require('multer'); 

var configDB = require('./config/database'); 

var app = express(); 

// configuration =============================================================== 
mongoose.connect(configDB.url); // connect to our database 
require('./config/passport')(passport); // pass passport for configuration 

// view engine setup 
app.set('views', path.join(__dirname, 'views')); 
app.set('view engine', 'ejs'); 

// uncomment after placing your favicon in /public 
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 
//app.use(logger('dev')); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: false })); 
app.use(cookieParser()); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.use(session({ 
    secret: 'secret', 
    resave: false, 
    saveUninitialized: false 
})); // session secret 
app.use(passport.initialize()); 
app.use(passport.session()); // persistent login session 
app.use(flash()); // use connect-flash for flash messages stored in session 
app.use(multer({ // use multer for processing of multipart/form-data 
    dest: 'uploads/', 
    rename: function (fieldname, filename){ 
     return filename.replace(/\W+/g, '-').toLowerCase() + Date.now(); 
    }, 
    onFileUploadStart: function (file){ 
     console.log(file.fieldname + ' upload starting...'); 
    }, 
    onFileUploadData: function (file, data){ 
     console.log(data.length + ' of ' + file.fieldname + ' arrived'); 
    }, 
    onFileUploadComplete: function (file){ 
     console.log(file.fieldname + ' uploaded to ' + file.path); 
    } 
}).single('avatar')); 

// routes ====================================================================== 
require('./routes/routes')(app, passport); // load our routes and pass in our app and fully configured passport 

// catch 404 and forward to error handler 
app.use(function(req, res, next) { 
    var err = new Error('Not Found'); 
    err.status = 404; 
    next(err); 
}); 

// set production environment 
app.set('env', 'production'); 

// set development environment 
//app.set('env', 'development'); 

// error handlers 

// development error handler 
// will print stacktrace 
if (app.get('env') === 'development') { 
    app.use(function(err, req, res, next) { 
    res.status(err.status || 500); 
    res.render('pages/error', { 
     message: err.message, 
     error: err 
    }); 
    }); 
} 

// production error handler 
// no stacktraces leaked to user 
app.use(function(err, req, res, next) { 
    res.status(err.status || 500); 
    res.render('pages/error', { 
    message: err.message, 
    error: {} 
    }); 
}); 


module.exports = app; 

而且,這些都是當前的目錄擁有的權限和權利(myuser的具有須藤權限)

[email protected]:~$ ls -dl /var/www 
drwxr-xr-x 3 root root 4096 Feb 4 01:17 /var/www 

[email protected]:~$ ls -dl /var/www/myapp 
drwxr-xr-x 3 myuser myuser 4096 Feb 4 01:18 /var/www/myapp 

[email protected]:~$ ls -dl /var/www/myapp/MyApp 
drwxrwxr-x 4 myuser myuser 4096 Feb 4 16:49 /var/www/myapp/MyApp 

[email protected]:~$ ls -dl /var/www/myapp/MyApp/MyApp 
drwxrwxr-x 12 myuser myuser 4096 Feb 4 16:57 /var/www/myapp/MyApp/MyApp 

[email protected]:~$ ls -dl /var/www/myapp/MyApp/MyApp/uploads 
drwxrwxr-x 2 myuser myuser 4096 Feb 4 02:04 /var/www/myapp/MyApp/MyApp/uploads 

通過方式,更改爲{ dest: './uploads/'}給出了相同的錯誤。

+0

爲myuser可能有sudo的特權,但沒有使用'sudo'爲'mkdir'你會得到拒絕訪問。我希望你的應用程序不能以root權限運行,這是安全噩夢的祕訣。 – migg

+0

@migg我該如何讓應用程序使用sudo mkdir?在通過命令行嘗試時,我沒有任何問題,這是應用程序可以解決問題。另外,我確定我的應用程序不能以root權限運行。 – flizana

+0

我認爲你不應該這樣做,即使這是可能的,從安全的角度出發。你正在使用的模塊沒有這樣做。只需將'uploads'文件夾的權限更改爲該應用程序正在運行的用戶可寫。 – migg

回答

0

如果您正在使用開發應用程序的任何IDE然後總是須藤模式下運行的應用程序。例如 。如果您使用的是webstorm,那麼請始終在文件中運行它的webstorm.sh,如下所示。

sudo的慶典/opt/webstorm/bin/webstorm.sh

+2

不知道這是一個合適的解決辦法,會更好張貼評論或相似。如果您認爲這是一個答案,請擴展更多信息,並瞭解如何解決OP的問題 – Draken