user2867106
user2867106

Reputation: 1131

SailsJS: add a middleware before the defined express middlewares for debugging

General Problem

Sails JS is built upon express JS, for debugging reasons I would like to inject a middleware or a function in Sails JS before cookieParser/bodyParser, I expect that Sails JS wrapped the following:

app.use(cookieParser()); app.use(bodyParser()); etc...

I would like to inject my own middleware function before these injections, how can I do that? for example in order to track the initial request.

Specific problem:

I integrated with Passport JS, sensitive users info are in request (see below), I am pretty sure this is due to request parsing middleware like cookieParser/bodyParser, but I would like to know how to confirm this myself.

(I would also be happy for a confirmation from you)

When I print the request, the user information is there, specifically, the password ("password: '$2a$10$rfRptIm7o1BKD1Qdr7yPUeWVisEHyZciCdD0ebivLAm8PPVRUicES',")

Here is the partial request:

    _passport: 
    { instance: 
      { _key: 'passport',
        _strategies: [Object],
        _serializers: [Object],
        _deserializers: [Object],
        _infoTransformers: [],
        _framework: [Object],
        _userProperty: 'user',
        Authenticator: [Function: Authenticator],
        Passport: [Function: Authenticator],
        Strategy: [Object],
        strategies: [Object] },
     session: { user: '532ea818e6221c90251e9342' } },
    user: 
    { username: 'nizar',
     password: '$2a$10$rfRptIm7o1BKD1Qdr7yPUeWVisEHyZciCdD0ebivLAm8PPVRUicES',
     createdAt: Sun Mar 23 2014 11:23:36 GMT+0200 (Jerusalem Standard Time),
     updatedAt: Sun Mar 23 2014 11:23:36 GMT+0200 (Jerusalem Standard Time),
     id: '532ea818e6221c90251e9342' },

while in the model I toJSON and deleted the password:

toJSON: function() {
  var obj = this.toObject();
  delete obj.password;
  return obj;
}

Upvotes: 1

Views: 1678

Answers (2)

bnuhero
bnuhero

Reputation: 2734

1.General Problem

For Sails 0.9.x, the middlwares loaded by the sails server are defined in sails/lib/express/index.js. As you can see, the custom middlware defined in config/express.js is used after cookieParser, session, bodyParser and methodOverride. To inject a custom middleware before cookieParser and bodyParser, you can override the cookieParser or modify sails/lib/express/index.js directly.

For Sails 0.10.x, you can define a custom loadMiddleware function (default implementation is in sails/lib/hooks/http/loadMiddleware.js) in config/express.js. Scott Gress has explained this in detail.

2.Specific Problem

If you don't want the request object to include the password information, call toJSON() in the callback function of deserializeUser:

passport.deserializeUser(function(id, done) {
  User.findOneById(id).done(function(err, user) {
    done(err, user.toJSON());
  });
});

and in the callback function of the strategy definition:

passport.use('local',
    new LocalStrategy({
      usernameField: 'userename',
      passwordField: 'password'
    },
    function(username, password, done) {
      User.findOne({ name: username}).done(function(err, user) {
        if (err) return done(err);

        if (!user) {
          return done(null, false, {message: 'Unknown user'+username});
        }; 

        if (!user.validatePassword(password)) {
          return done(null, false, {message: 'Invalid password!'});
        };

        return done(null, user.toJSON());
      });
    }
));

Upvotes: 1

sgress454
sgress454

Reputation: 24958

For Sails v0.10, you can follow the procedure in this answer to insert custom middleware before the body parser. In v0.9.x, you'd have to create your own bodyParser callback and add the middleware in there; see this answer for more info.

However in your case I'm not sure any of this is necessary. Passport is adding user data to the request object on the server as a convenience, but it's not actually being transmitted in the request. So, there's no sensitive data out in the open--it's just in memory. Your only concern is to keep it from being sent back to the client, which you're already doing with your toJSON method on the User model.

Upvotes: 1

Related Questions