0

I have a web server (developped with sailsjs) that acts as an authentication API. Basically, for each request, it:
- gets the Bearer token in the Authorization header
- gets the incoming url and checks if the requested user has the right on this particular resource.

I'd like to be able to do this check before receiving the body of the request (that could be several Gigabytes files) and, once the authorization is ok, send those file to another webserver dedicated to the file processing.

Could this check be done before receiving the body ?

In a config/oaut2.js file I've added the following:

module.exports = {
    express: {
        customMiddleware: function(app){

        /***** OAuth authentication before accepting large files *****/
        app.post('/test',
            function(req, res, next){
                passport.authenticate(
                    'bearer',
                    function(err, user, info)
                    {
                        if ((err) || (!user))
                        {
                            res.send(401);
                            return;
                        }
                        delete req.query.access_token;
                        req.user = user;
                        return next();
                    }
                )(req, res);
            },
            function(req, res){
                // HERE WILL BE HANDLED THE LARGE FILE
                return res.json({status: 'ok'});
            });
        }
    }
}

But even if the Bearer token is not correct, the second function (the one handling the files) is triggered

Luc
  • 16,604
  • 34
  • 121
  • 183
  • 1
    Side note that for most of the Internet, assuming a multi-gigabyte upload can complete in a single request is not a good assumption. You might want to consider an approach that supports resuming upload if a transfer is interrupted midway. – Peter Lyons Jul 30 '14 at 07:59

2 Answers2

0

Sure, at least with plain express. I can't comment on any sailsjs specifics. Just make sure your middleware or request handler that does authorization comes before the handler that streams the body to an upstream server.

app.post('/big-file-upload', checkBearerToken, upstream);

As long as if authentication fails, checkBearerToken does not call next(), you can abandon the request without processing the body.

For sailsjs, it looks like you can modify the middleware order with the steps described in this answer.

Community
  • 1
  • 1
Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
  • I've setup a basic sailsjs project to test this but the checkBearerToken is triggered once the whole request (including the big file) has been received. Sails uses plain express, it just wrap the things in a clean manner. – Luc Jul 30 '14 at 09:24
  • node/Express support streaming, and invoke middleware/handlers as soon as the headers have arrived but the body is streamed. See [raw-body](https://github.com/stream-utils/raw-body) for an example. Are you sure you don't have an `app.use(bodyParser)` configured in your app somewhere? Posting a minimal code snippet as per the good question guidelines would help answer your question more efficiently. – Peter Lyons Jul 30 '14 at 14:58
  • I'm using sailsjs as my backend framework, that may be the reason why the bodyParser is called right away. I've added some code to illustrate but even if the Bearer is incorrect the bodyPArser is called (and raised an error) – Luc Oct 02 '14 at 14:28
0

There isn't really a way to get in front of body parsing in Sails 0.9.x. See here: https://github.com/balderdashy/sails/blob/v0.9.16/lib/express/index.js#L161

In that code, you can see that the customMiddleware is use()'d after the body parser.

If you want more fine grained control over the middleware, you'll need to upgrade to Sails 0.10.x, and follow the link in Peter Lyons answer for more details about doing that.

Chad
  • 2,161
  • 1
  • 19
  • 18