2016-02-04 198 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