Rectangle 27 0

I'll leave the answer below in case it helps, but the answer is actually quite simple: you need to move the two calls to app.use(passport) above the call to app.use(multer). Each step in the express chain is processed in order, so if you wish reject a bad auth attempt, do it before you handle the incoming file upload.

There is probably a better way to do this, but this should get you started. Change your express config to use a closure and you'll have full access to the req variable.

app.use(function(req, res, next) {
  var handler = multer({
    dest: wwwroot + path.sep + 'uploaded' + path.sep, 
    onFileUploadStart: function (file) {
      // You now have access to req
      console.dir(req);
      console.log(file.fieldname + ' is starting ...')
    },
    onFileUploadComplete: function (file) {
      console.log(file.fieldname + ' uploaded to  ' + file.path)
    }
  });
  handler(req, res, next);
});
app.use(multer)

all

router.post('/', auth.hasRole('admin'), multer(uploadPreferences), controller.create);

node.js - Nodejs Express 4 Multer | Stop file upload if user not autho...

node.js express multer
Rectangle 27 0

Okay I think I got a solution for you. It is not a complete solution for my own problems, but it serves for your specific case, which is checking if a user is authorized through Passport before downloading the file.

The trick is to use middlewares in your post handlers to do one thing at a time. First passport will be called to put user object in the req object. Then, you check if user is authenticated. If it is the case, you download the file and then use it. Here's a sample:

//don't add multer as a middleware to all requests. 
//If you do this, people will be able to upload files
//in ALL YOUR 'post' handlers!!! 
var Multer = require('multer');

//this is a middleware to check if user is authenticated
function check(req, res, next){
    if(req.isAuthenticated()){
        console.log(req.user);
        next();
    }
    else{
        res.send(401);
    }
}

//this is a middleware to be called after file is downloaded
function finish(req, res, next){
    var filePath = req.files.file.path;
    res.send("Hello " + req.user.name + "! Your file was uploaded to " + filePath);
}

//this is the route handler. First check auth. If so, 
//proceed to multer middleware to download file
//lastly, use the file as you need
app.post('/test', [check, Multer(), finish]);

This only works because Passport does not use body data to authenticate the user: it uses sessions that are not in the body. So you can use Passport and get user data, but you can't, for instance, be sure you have all non-file fields parsed before start downloading the file (since they come all together in express req stream)

what about congifuring multer with dest, limits, onFileUploadStart, onFileUploadData, onFileUploadComplete, and other options? Would that go inside the parentheses for Multer()?

Yes. You'd have to set the configuration for your specific requests. Most of my requests require different configurations and handling so that's what I do.

node.js - Nodejs Express 4 Multer | Stop file upload if user not autho...

node.js express multer
Rectangle 27 0

From the multer api doc "You can even stop a file from being uploaded - just return false from the event handler. The file won't be processed or reach the file system."

If I had access to the request object, from which I could check the user, that would be possible... But I have not

node.js - Nodejs Express 4 Multer | Stop file upload if user not autho...

node.js express multer