Sails.js + Passport.js: passport.initialize() midd

2019-07-12 19:32发布

问题:

I am using Sails.js and trying to use Passport.js with a REST API. But I am facing the following error when I try to call my login function in my controller:

    /Users/Michael/Development/DictationProject/sails/20151010/dictee/node_modules/passport/lib/http/request.js:44
    if (!this._passport) { throw new Error('passport.initialize() middleware not in use'); }
                           ^
Error: passport.initialize() middleware not in use
    at IncomingMessage.req.login.req.logIn (/Users/Michael/Development/DictationProject/sails/20151010/dictee/node_modules/passport/lib/http/request.js:44:34)
    at /Users/Michael/Development/DictationProject/sails/20151010/dictee/api/controllers/AuthController.js:20:17
    at Strategy.strategy.success (/Users/Michael/Development/DictationProject/sails/20151010/dictee/node_modules/passport/lib/middleware/authenticate.js:194:18)
    at verified (/Users/Michael/Development/DictationProject/sails/20151010/dictee/node_modules/passport-local/lib/strategy.js:83:10)
    at /Users/Michael/Development/DictationProject/sails/20151010/dictee/config/passport.js:53:18

My config/http.js file is configured as below (Session is loaded before passportInit and passportSession):

passportInit    : require('passport').initialize(),
passportSession : require('passport').session(),
flash           : require('connect-flash'),


      order: [
        'startRequestTimer',
        'cookieParser',
        'session',
        'passportInit',     
        'passportSession', 
        'myRequestLogger',
        'bodyParser',
        'handleBodyParserError',
        'compress',
        'methodOverride',
        'poweredBy',
        '$custom',
        'flash',
        'router',
        'www',
        'favicon',
        '404',
        '500'
      ],

Don't understand what is wrong...

EDIT:

It seems to be coming from passport.use() in config/passport.js :

passport.use('login', new LocalStrategy({
    passReqToCallback : true,
    usernameField: 'email',
    passwordField: 'password'
  },
  function(req, email, password, done) {
    console.log('In passport.use login');
    // check in mongo if a user with email exists or not
    User.findOne({ 'email' : email }, function (err, user) {
    // In case of any error, return using the done method
      if (err) { 
        console.log('Error passport.use login');
        return done(err);
      }
      // Username does not exist, log error & redirect back
      if (!user) {
        console.log('User Not Found with email '+email);
        return done(null, false, req.flash('message', 'User Not found.'));
      }

      console.log('One user matching this email address found');

      // User exists but wrong password, log the error 
      bcrypt.compare(password, user.password, function (err, res) {
          if (!res) {
            console.log('Invalid Password');
            return done(null, false, req.flash('message', 'Invalid Password'));
          }

        // User and password both match, return user from 
        // done method which will be treated like success
        console.log('One user matching this email address and password found');

          var returnUser = {
            name: user.name,
            email: user.email,
            createdAt: user.createdAt,
            id: user.id
          };

          console.log('Returning User: ' + returnUser);
          return done(null, returnUser,
            req.flash('message', 'Logged In Successfully')
          );
        });
    });
  }
));

回答1:

Following the recommendations from Sails.js creator on passport: https://github.com/balderdashy/sails/pull/1224

Issue is solved by putting the Passport middleware in the config/policies.js file:

var passport = require('passport');

module.exports.policies = {
    '*': [
        // Initialize Passport
        passport.initialize(),

        // Use Passport's built-in sessions
        passport.session()
    ]
}


回答2:

I am using Sails.js and tryong to use Passport.js with a REST API

You do it wrong. You don't need to call initialize() and session() methods. If you really have REST API then it stateless and doesn't store information about users in session.

My middleware configuration looks like this and everything works great with passport and many other strategies like passport-facebook-token and passport-google-plus-token.

order: [
  'compress',
  'keepAlive',
  'bodyParser',
  '$custom',
  'router',
  '404',
  '500'
]