angular-fullstack / generator-angular-fullstack

Yeoman generator for an Angular app with an Express server
https://awk34.gitbook.io/generator-angular-fullstack
6.13k stars 1.24k forks source link

Error: Failed to serialize user into session at pass #667

Closed Exegetech closed 9 years ago

Exegetech commented 9 years ago

Hello, I was trying to incorporate linkedin Oauth 1.0. Unfortunately, I didn't scaffold the app with the option of Twitter Oauth (which is also 1.0). I however, tried to see what the codes were for Twitter Oauth 1.0 by scaffolding another app with Twitter Oauth.

As far as I follow, I have all the codes necessary.

exports.setup = function (User, config) {
  passport.use(new LinkedInStrategy({
      consumerKey: config.linkedIn.clientID,
      consumerSecret: config.linkedIn.clientSecret,
      callbackURL: config.linkedIn.callbackURL,
      profileFields: config.linkedIn.profileFields
    },
    function(token, tokenSecret, profile, done) {
      User.findOne({
        'linkedIn.id': profile.id
      }, function(err, user) {
        if (!user) {
          var linkedInFields = parseLinkedIn(profile);
          user = new User(linkedInFields);
          user.save(function(err) {
            if (err) {
              done(err);
            }
            return done(err, user);
          });
        } else {
          return done(err, user);
        }
      });
    }
  ));
};
router
  .get('/', passport.authenticate('linkedin', {
    failureRedirect: '/signup',
    scope: ['r_fullprofile', 'r_emailaddress', 'r_contactinfo']
  }))

  .get('/callback', passport.authenticate('linkedin', {
    failureRedirect: '/signup'
  }), auth.setTokenCookie);
  // Persist sessions with mongoStore
  // We need to enable sessions for passport linkedin because its an oauth 1.0 strategy
  app.use(session({
    secret: config.secrets.session,
    resave: true,
    saveUninitialized: true,
    store: new mongoStore({ mongoose_connection: mongoose.connection })
  }));

but I keep getting this error,

Error: Failed to serialize user into session at pass (/Users/Christian/Desktop/HireDot/hireDot/node_modules/passport/lib/authenticator.js:277:19) at Authenticator.serializeUser (/Users/Christian/Desktop/HireDot/hireDot/node_modules/passport/lib/authenticator.js:295:5) at IncomingMessage.req.login.req.logIn (/Users/Christian/Desktop/HireDot/hireDot/node_modules/passport-linkedin/node_modules/passport-oauth/node_modules/passport/lib/passport/http/request.js:43:29) at Strategy.strategy.success (/Users/Christian/Desktop/HireDot/hireDot/node_modules/passport/lib/middleware/authenticate.js:228:13) at verified (/Users/Christian/Desktop/HireDot/hireDot/node_modules/passport-linkedin/node_modules/passport-oauth/lib/passport-oauth/strategies/oauth.js:151:16) at Promise.<anonymous> (/Users/Christian/Desktop/HireDot/hireDot/server/auth/linkedIn/passport.js:52:20) at Promise.<anonymous> (/Users/Christian/Desktop/HireDot/hireDot/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8) at Promise.EventEmitter.emit (events.js:98:17) at Promise.emit (/Users/Christian/Desktop/HireDot/hireDot/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38) at Promise.fulfill (/Users/Christian/Desktop/HireDot/hireDot/node_modules/mongoose/node_modules/mpromise/lib/promise.js:97:20)
Exegetech commented 9 years ago

Sorry, figured it out, I need to modify my route to be

router
  .get('/', passport.authenticate('linkedin', {
    failureRedirect: '/signup',
    scope: ['r_fullprofile', 'r_emailaddress', 'r_contactinfo'],
    session: false
  }))

  .get('/callback', passport.authenticate('linkedin', {
    failureRedirect: '/signup',
    session: false
  }), auth.setTokenCookie);

Anyone care to explain why?

kingcody commented 9 years ago

@christiansakai thanks for documenting this. From the passport.authenticate docs:

After successful authentication, Passport will establish a persistent login session. This is useful for the common scenario of users accessing a web application via a browser. However, in some cases, session support is not necessary. For example, API servers typically require credentials to be supplied with each request.

angular-fullstack uses JWT for authentication so passport does not need to establish the session as that is taken care of by auth.setTokenCookie.

/**
 * Set token cookie directly for oAuth strategies
 */
function setTokenCookie(req, res) {
  if (!req.user) return res.json(404, { message: 'Something went wrong, please try again.'});
  var token = signToken(req.user._id, req.user.role);
  res.cookie('token', JSON.stringify(token));
  res.redirect('/');
}

Therefore session: false tells passport to skip/ignore session establisment AND verification.

Does that help out?

Exegetech commented 9 years ago

Thank you, yes it definitely clear things out. Sorry I forgot to close the issue.