2013-03-25 15 views
18

登錄時需要「記住我」複選框,如this。 我用護照如何在護照上添加「記住我」至我的應用程序

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()); 

req.body.rememberme是真實的,當req.body.rememberme是假的用戶記得我無法登錄前添加一箇中間件。 我也嘗試connect-ensure-login,但它仍然是錯誤的。

和另一個問題:我應該何時刪除我的數據庫中的cookie以及如何?

:)

其他代碼是完全一樣的護照指南

路線:

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'); }); 

會議:

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); 
    }); 
}); 

和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'}); 
    } 
}); 
})); 

我注意到Express只會在散列值發生變化時更新cookie。所以我已經修改了代碼中間件

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(); 
}); 

現在我可以「記住我」登錄,但它僅適用於鉻和Firefox在Ubuntu。我仍然無法使用Win7和Android上的Chrome和Firefox上的「記住我」複選框登錄。

我在win7上查看chrome上的「/ login」時檢查了響應標題,並且它在Ubuntu上與它具有相同的「Set-Cookie」字段,爲什麼它無法工作?


時間不同步......所以我發佈了一個額外的時間字段。

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

和 「與rememberMe」 中間件:

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(); 
}); 
+0

這不是錯誤的嗎?如果'rememberme == true'意味着cookie不應該過期?您需要發佈更多的代碼,因爲您需要的不僅僅是這三個中間件 – pfried 2013-03-25 07:13:09

+0

如果'rememberme == true',cookie會有一個過期(在這種情況下爲3分鐘),否則該cookie會成爲一個會話cookie(當瀏覽器會話完成)。但我同意:需要更多的代碼。 – robertklep 2013-03-25 07:21:38

+0

這段代碼很混亂。你應該分開擔憂。 'serialize'和'deserialize'函數是通過它的id(使用數據庫id)並序列化到一個會話cookie(如果你擔心的話,它不會以明文形式存在的話)來獲取用戶。不要混入一些可疑的安全代碼 – pfried 2013-03-25 08:16:54

回答

1

確保app.use(express.bodyParser())放在你的中間件之上,因爲你是靠req.body.rememberme

25

我有完全一樣的問題,因爲你。以下代碼適用於我:

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('/'); 
}); 
+0

這正是我所需要的,謝謝。 – 2015-05-10 09:31:22

+0

我已經將示例時間從3分鐘(這比大多數會話少)編輯爲30天。我在想,3分鐘是不記得我的模式,'... expires = false;'意味着永不過期。 – rjmunro 2016-01-15 17:04:11

5

現在有一個Passport戰略,用於添加由Jared Hanson寫的Remember Me功能。

https://github.com/jaredhanson/passport-remember-me

這是通過發出一個獨特的記憶,我每次在開始消耗會議期間標記接下來的(以備將來使用無效的。)因此,這很可能是一個更解決方案。

+0

如果你的應用程序是koa.js應用程序,https://github.com/clthck/passport-remember-me適合我。它實際上是jaredhanson原始回購的一個分支,它只是增加了對koa.js應用程序的支持(以及[koa-passport](https://github.com/rkusa/koa-passport)) – artificis 2016-12-26 08:20:14

+0

還值得注意的是,對於真正的「記住我」 - 你需要某種類型的令牌的長期持久性,無論是緩存還是數據庫 - 否則服務器會將它們存儲在內存中。您希望能夠重新啓動服務器,並且仍然有記住我的令牌有效 – tcmoore 2017-09-29 17:20:15

相關問題