У меня есть сервер приложений Node.js при работе на компьютере Ubuntu 14.04 LTS, но когда я пытаюсь подключиться через браузер, на лентах PM2 появляется следующая ошибка:Ошибка Разрешение 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 имеет привилегии SUDO)
[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/'}
, дает ту же ошибку.
MyUser может иметь привилегии SUDO, но без использования '' sudo' к mkdir' вы получите доступ запрещен. И я надеюсь, что ваше приложение не будет работать с привилегиями root, это рецепт кошмаров безопасности. – migg
@migg Как заставить приложение использовать sudo для mkdir? У меня нет проблем при попытке выполнить его через командную строку, это приложение вызывает проблемы. Кроме того, я уверен, что мое приложение не запускается с правами root. – flizana
Я думаю, вы не должны этого делать, даже если это было возможно, с точки зрения безопасности. Модуль, который вы используете, не делает этого. Просто измените разрешения на папку 'uploads' для записи для пользователя, на котором запущено приложение. – migg