如何使用 Express 和 PassportJS 正确报告无效登录?
Posted
技术标签:
【中文标题】如何使用 Express 和 PassportJS 正确报告无效登录?【英文标题】:How can I report an invalid login properly with Express and PassportJS? 【发布时间】:2012-03-30 05:38:27 【问题描述】:我已成功在我的 Express/Mongoose 网络应用中实现了本地护照,但我无法弄清楚如何正确呈现失败的登录消息。
这是我的登录路径:
app.get('/login', function(req, res)
res.render('user/login',
);
);
使用这样的路由,我应该如何报告无效登录?如果登录成功,它会将id
/username
写入req.user
对象,但这对"GET /login"
路由没有帮助,因为如果登录成功,您将被重定向到您想去的页面.
这意味着当您GET
登录页面时,req.user
将始终是undefined
。
我希望能够写出一条消息,例如“哟,登录无效!”当以下情况发生时:
-
用户不存在。
提供的密码不匹配,但用户存在。
我可能想根据发生的情况输出不同的消息。
当我实现 LocalStrategy 时,我使用了以下代码:
passport.use(new LocalStrategy(
usernameField: 'email'
,
function(email, password, fn)
User.findOne('login.email': email, function(err, user)
// Error was thrown.
if (err)
return fn(err);
// User does not exist.
if (!user)
return fn(null, false);
// Passwords do not match.
if (user.login.password != utility.encryptString(user.login.salt + password))
return fn(null, false);
// Everything is good.
return fn(null, user);
);
));
正如您所见,存在一些问题,但这就是 PassportJS 的作者设置他的应用程序的方式。我们应该如何访问 Strategy 返回的内容?
如果它抛出一个错误,我什至应该调用什么来访问err
?
谢谢。
【问题讨论】:
【参考方案1】:在最新版本的 Passport 中,我添加了对 flash 消息的支持,这使您可以轻松地完成您的要求。
您现在可以向done
提供第三个参数,其中可以包含失败消息。例如:
if (user.login.password != utility.encryptString(user.login.salt + password))
return fn(null, false, message: 'yo, invalid login!' );
然后,将failureFlash
设置为true
作为authenticate()
的选项。
passport.authenticate('local', successRedirect: '/',
failureRedirect: '/login',
failureFlash: true );
在这种情况下,如果认证失败,消息会被设置在flash中,供你再次显示登录页面时渲染。
自定义回调也非常好。内置选项只是让完成常见任务变得更简单。
另外,我很好奇:您提到样本存在问题。你认为应该改进什么?我想让这些例子尽可能好。谢谢!
(有关更多详细信息,请参阅问题 #12 上的 comment)。
【讨论】:
故障闪现让它变得容易多了。但是,我确实注意到传递给done
的任何err
或OP 的fn
对于该工作必须为null 或false - 我花了一分钟才意识到这一点。【参考方案2】:
您可以使用自定义回调或中间件功能来获得更多控制权。有关示例,请参阅指南的 Authentication 部分。
例如,自定义回调可能如下所示:
app.get('/login', function(req,res,next)
passport.authenticate('local', function(err,user)
if(!user) res.send('Sorry, you\'re not logged in correctly.');
if(user) res.send('Skeet skeet!');
)(req,res,next);
);
或者,您始终可以重定向两个响应:
app.get('/login',
passport.authenticate('local', successRedirect: '/winner',
failureRedirect:'/loser' ));
或者用简单的中间件重定向失败:
app.get('/login', ensureAuthenticated,
function(req,res)
// successful auth
// do something for-the-win
);
// reusable middleware
function ensureAuthenticated(req,res,next)
if(req.isAuthenticated()) return next();
res.redirect('/login/again'); // if failed...
【讨论】:
不错,自定义回调方法看起来可行。谢谢。两种替代解决方案如何做同样的事情呢?您不会在 POST 请求上执行成功/失败重定向示例吗?这就是我正在做的。第二种选择只是强制登录以访问页面的标准方法?就像,这就是您要在想要控制访问的页面上放置的内容(用户配置文件等)。我将把你标记为自定义回调的答案。 我认为您的问题是“我如何响应身份验证成功或失败?”,这三种方法是不同的方法。对于替代方案,您只是将客户端发送到不同的路线来处理响应......因为我不知道您的实施细节,所以由您决定什么是最好的。是的,选项 3 是对需要身份验证的页面强制执行身份验证的好方法。以上是关于如何使用 Express 和 PassportJS 正确报告无效登录?的主要内容,如果未能解决你的问题,请参考以下文章
Express + PassportJS 无法读取 flash 消息
在 React/Express 中使用 PassportJS 进行 Google OAuth 时出现 CORS 错误