Jef*_*hen 65 javascript logout node.js express passport.js
我无法让我的系统注销PassportJS.似乎正在调用注销路由,但它不会删除会话.如果用户没有以特定路线登录,我希望它返回401.我调用authenticateUser来检查用户是否已登录.
非常感谢!
/******* This in index.js *********/
// setup passport for username & passport authentication
adminToolsSetup.setup(passport);
// admin tool login/logout logic
app.post("/adminTool/login",
passport.authenticate('local', {
successRedirect: '/adminTool/index.html',
failureRedirect: '/',
failureFlash: false })
);
app.get('/adminTool/logout', adminToolsSetup.authenticateUser, function(req, res){
console.log("logging out");
console.log(res.user);
req.logout();
res.redirect('/');
});
// ******* This is in adminToolSetup ********
// Setting up user authentication to be using user name and passport as authentication method,
// this function will fetch the user information from the user name, and compare the password for authentication
exports.setup = function(passport) {
setupLocalStrategy(passport);
setupSerialization(passport);
}
function setupLocalStrategy(passport) {
passport.use(new LocalStrategy(
function(username, password, done) {
console.log('validating user login');
dao.retrieveAdminbyName(username, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
// has password then compare password
var hashedPassword = crypto.createHash('md5').update(password).digest("hex");
if (user.adminPassword != hashedPassword) {
console.log('incorrect password');
return done(null, false, { message: 'Incorrect password.' });
}
console.log('user validated');
return done(null, user);
});
}
));
}
function setupSerialization(passport) {
// serialization
passport.serializeUser(function(user, done) {
console.log("serialize user");
done(null, user.adminId);
});
// de-serialization
passport.deserializeUser(function(id, done) {
dao.retrieveUserById(id, function(err, user) {
console.log("de-serialize user");
done(err, user);
});
});
}
// authenticating the user as needed
exports.authenticateUser = function(req, res, next) {
console.log(req.user);
if (!req.user) {
return res.send("401 unauthorized", 401);
}
next();
}
Run Code Online (Sandbox Code Playgroud)
jlm*_*kes 75
布莱斯的答案很棒,但我仍然注意到了一个重要的区别; Passport指南建议使用.logout()(也有别名.logOut()):
app.get('/logout', function(req, res){
req.logout();
res.redirect('/'); //Can fire before session is destroyed?
});
Run Code Online (Sandbox Code Playgroud)
但如上所述,这是不可靠的.我发现它在执行Brice的建议时表现得如预期:
app.get('/logout', function (req, res){
req.session.destroy(function (err) {
res.redirect('/'); //Inside a callback… bulletproof!
});
});
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
Bri*_*ice 41
陷入同样的问题.使用req.session.destroy();而不是req.logout();工作,但我不知道这是否是最好的做法.
esp*_*esp 10
session.destroy 可能不够,为了确保用户完全注销,您还必须清除会话cookie.
这里的问题是,如果您的应用程序也被用作单页面应用程序的API(不推荐但很常见),那么可能会有一些请求由快递处理,在注销之前开始并在注销后结束.如果是这种情况,则此较长时间运行的请求将在删除后以redis还原会话.并且因为下次打开页面时浏览器仍然具有相同的cookie,您将成功登录.
req.session.destroy(function() {
res.clearCookie('connect.sid');
res.redirect('/');
});
Run Code Online (Sandbox Code Playgroud)
这就是可能发生的事情:
理想情况下,您需要对api调用使用令牌身份验证,并且仅在仅加载页面的Web应用程序中使用会话,但即使您的Web应用程序仅用于获取api令牌,此竞争条件仍然可行.
我遇到了同样的问题,而且根本不是Passport功能的问题,而是我调用/logout路线的方式.我使用fetch来调用路由:
(坏)
fetch('/auth/logout')
.then([other stuff]);
Run Code Online (Sandbox Code Playgroud)
结果这样做不会发送cookie所以会话不会继续,我想这些res.logout()获取应用于不同的会话?无论如何,执行以下操作会修复它:
(好)
fetch('/auth/logout', { credentials: 'same-origin' })
.then([other stuff]);
Run Code Online (Sandbox Code Playgroud)
我使用了req.logout()andreq.session.destroy()并且工作正常。
server.get('/logout', (req, res) => {
req.logout();
req.session.destroy(()=>{
res.redirect('/');
});
});
Run Code Online (Sandbox Code Playgroud)
顺便提一下,我使用 Redis 作为会话存储。
我有同样的问题,资本O修复了它;
app.get('/logout', function (req, res){
req.logOut() // <-- not req.logout();
res.redirect('/')
});
Run Code Online (Sandbox Code Playgroud)
我最近遇到了同样的问题,但没有一个答案为我解决了这个问题。可能是错误的,但它似乎与竞争条件有关。
将会话详细信息更改为下面的选项似乎已经为我解决了这个问题。我现在已经测试了大约 10 次,一切似乎都正常工作。
app.use(session({
secret: 'secret',
saveUninitialized: false,
resave: false
}));
Run Code Online (Sandbox Code Playgroud)
基本上我只是改变saveUninitialized并resave从true到false。这似乎解决了这个问题。
仅供参考,我req.logout();在注销路径中使用标准方法。我没有像其他人提到的那样使用会话销毁。
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
53508 次 |
| 最近记录: |