Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add "Remember Me" to my app with passport

I need a "Remember Me" checkbox when logging in like this . And I add a middleware before using passport

app.use(function(req, res, next) {   if (req.method == 'POST' && req.url == '/login') {     if (req.body.rememberme) {       req.session.cookie.maxAge = 1000 * 60 * 3;     } else {       req.session.cookie.expires = false;     }   }   next(); }); app.use(passport.initialize()); app.use(passport.session()); 

I can not login when req.body.rememberme is true and the user is remembered when req.body.rememberme is false. I also tried connect-ensure-login and it still wrong.

and another question: when should I delete the cookies in my database and how?

:)

Other code is exactly the same as the passport guide

route:

app.get('/', passport.authenticate('local', {   failureRedirect: '/login' }), function(req, res) {   res.redirect('/user/home'); }); app.post('/login', passport.authenticate('local', {   failureRedirect: '/login' }), function(req, res) {   res.redirect('/user/home'); }); 

sessions:

passport.serializeUser(function(user, done) {   var CreateAccessToken = function() {     var token = user.GenerateSalt();     User.findOne({       accessToken: token     }, function(err, existingUser) {       if (err)         return done(err);       if (existingUser) {         CreateAccessToken();       } else {         user.set('accessToken', token);         user.save(function(err) {           if (err)             return done(err);           return done(null, user.get('accessToken'));         })       }     });   };   if (user._id)     CreateAccessToken(); }); passport.deserializeUser(function(token, done) {   User.findOne({     accessToken: token   }, function(err, user) {     if (err)       return done(err);     return done(err, user);   }); }); 

and the strategie:

passport.use(new LocalStrategy(function(userId, password, done) {   User.findOne().or([{     username: userId   }, {     email: userId   }]).exec(function(err, user) {     if (err)       return done(err);     if (!user) {       return done(null, false, {         message: 'Invalid password or username'       });     }     if (user.Authenticate(password)) {       return done(null, user);     } else {       return done(null, false, {         message: 'Invalid password or username'       });     }   }); })); 

I noticed that Express will update the cookie only when hash value changed. so I have modified the code in the middleware

app.use(function(req, res, next) {   if (req.method == 'POST' && req.url == '/login') {     if (req.body.rememberme) {       req.session.cookie.maxAge = 1000 * 60 * 3;       req.session._garbage = Date();       req.session.touch();     } else {       req.session.cookie.expires = false;     }   }   next(); }); 

now I can login with "Remember Me", but it only works on chromium and firefox on Ubuntu. I still can not login with the "Remember Me" checkbox on chrome and firefox on Win7 and Android.

I checked response header when POST to "/login" on chrome on win7 and it had the same "Set-Cookie" field as it on Ubuntu, why it can not work?


Time is out of sync...so I post a extra time field.

$('#login').ajaxForm({   beforeSubmit: function(arr, $form, option) {     arr.push({       name: '__time',       value: (new Date()).toGMTString()     });   } }); 

and the "RememberMe" middleware:

app.use(function(req, res, next) {   if (req.method == 'POST' && req.url == '/login') {     if (req.body.rememberme) {       req.session.cookie.maxAge = moment(req.body.__time).add('m', 3) - moment();       req.session._garbage = Date();       req.session.touch();     } else {       req.session.cookie.expires = false;     }   }   next(); }); 
like image 644
QingYun Avatar asked Mar 25 '13 06:03

QingYun


1 Answers

I had exactly the same problem as you. The following code works for me:

app.post("/login", passport.authenticate('local',     { failureRedirect: '/login',       failureFlash: true }), function(req, res) {         if (req.body.remember) {           req.session.cookie.maxAge = 30 * 24 * 60 * 60 * 1000; // Cookie expires after 30 days         } else {           req.session.cookie.expires = false; // Cookie expires at end of session         }       res.redirect('/'); }); 
like image 61
BOC Avatar answered Sep 21 '22 00:09

BOC