Express用户认证中间件,它应该做多少?
Express user authentication middleware, how much should it do?
我正在尝试学习 Express 会话和身份验证处理。
例如:
app.post('/login', authCredentials, function(req, res) {
console.log("second")
});
function authCredentials(req, res, next) {
//this happens first
console.log(req.body) // => { username: etc, password: etc }
next();
}
我的问题是我的 authCredentials
函数应该做多少?
例如,如果凭证是正确的,我可以做类似的事情
res.redirect('/index')
。但是,一旦我这样做了,第二个功能有什么用呢?
其他问题:
- 我将如何处理无效凭据?
- 如果我根据凭据使
authCredentials
只是 return true
或 false
,这不会破坏中间件流程,因为它永远不会调用 next()
?
- 是否可以在之后的匿名回调中访问
authCredentials
中的任何内容?基本上在function(req, res) { }
?
您想将 authCredentials
中间件添加到每个需要身份验证的端点。 app.post('/login')
通常不需要任何内容,因为您首先要访问此端点以实际获取凭据。
当凭据为 correct/valid 时,您只需调用 next()
,工作流将跳转到下一个中间件或实际终点。如果出现错误,请使用 next(new Error('could not authenticate');
等错误对象调用 next()
。将错误路由添加到您的常规路由,错误将在那里处理:
app.use(function(err, req, res, next) {
res.render('error', err);
});
- 现在应该回答了。
- 中间件没有return值。它要么调用
next()
,要么通过调用 res.send()
. 以不同方式结束进程
- 有多种方法可以将变量从一个中间件传递到另一个中间件。最常见的可能是将所需的值附加到
req
参数。
authenticate
是下例中的异步函数:
function authCredentials(req, res, next) {
authenticate(req.body, function(err, user) {
if (err) {
return next(err);
}
req.user = user;
next();
});
}
答案取决于您的身份验证策略,即您是否使用会话标识符、访问令牌等
无论哪种情况,我都建议您从身份验证中分离出凭据交换(又名登录)。
function usernamePasswordExchange(req,res,next){
var username = req.body.username;
var password = req.body.password;
callToAuthService(username,password,function(err,user){
if(err){
next(err); // bad password, user doesn’t exist, etc
}else{
/*
this part depends on your application. do you use
sessions or access tokens? you need to send the user
something that they can use for authentication on
subsequent requests
*/
res.end(/* send something */);
}
});
}
function authenticate(req,res,next){
/*
read the cookie, access token, etc.
verify that it is legit and then find
the user that it’s associated with
*/
validateRequestAndGetUser(req,function(err,user){
if(err){
next(err); // session expired, tampered, revoked
}else{
req.user = user;
next();
}
});
}
app.post('/login',usernamePasswordExchange);
app.get('/protected-resource',authenticate,function(req,res,next){
/*
If we are here we know the user is authenticated and we
can know who the user is by referencing req.user
*/
});
免责声明:我在 Stormpath 工作,我们花了很多时间写作
身份验证代码 :) 我刚刚编写了我们最新的库,stormpath-sdk-express,
具体实现了我的建议
我正在尝试学习 Express 会话和身份验证处理。
例如:
app.post('/login', authCredentials, function(req, res) {
console.log("second")
});
function authCredentials(req, res, next) {
//this happens first
console.log(req.body) // => { username: etc, password: etc }
next();
}
我的问题是我的 authCredentials
函数应该做多少?
例如,如果凭证是正确的,我可以做类似的事情
res.redirect('/index')
。但是,一旦我这样做了,第二个功能有什么用呢?
其他问题:
- 我将如何处理无效凭据?
- 如果我根据凭据使
authCredentials
只是 returntrue
或false
,这不会破坏中间件流程,因为它永远不会调用next()
? - 是否可以在之后的匿名回调中访问
authCredentials
中的任何内容?基本上在function(req, res) { }
?
您想将 authCredentials
中间件添加到每个需要身份验证的端点。 app.post('/login')
通常不需要任何内容,因为您首先要访问此端点以实际获取凭据。
当凭据为 correct/valid 时,您只需调用 next()
,工作流将跳转到下一个中间件或实际终点。如果出现错误,请使用 next(new Error('could not authenticate');
等错误对象调用 next()
。将错误路由添加到您的常规路由,错误将在那里处理:
app.use(function(err, req, res, next) {
res.render('error', err);
});
- 现在应该回答了。
- 中间件没有return值。它要么调用
next()
,要么通过调用res.send()
. 以不同方式结束进程
- 有多种方法可以将变量从一个中间件传递到另一个中间件。最常见的可能是将所需的值附加到
req
参数。
authenticate
是下例中的异步函数:
function authCredentials(req, res, next) {
authenticate(req.body, function(err, user) {
if (err) {
return next(err);
}
req.user = user;
next();
});
}
答案取决于您的身份验证策略,即您是否使用会话标识符、访问令牌等
无论哪种情况,我都建议您从身份验证中分离出凭据交换(又名登录)。
function usernamePasswordExchange(req,res,next){
var username = req.body.username;
var password = req.body.password;
callToAuthService(username,password,function(err,user){
if(err){
next(err); // bad password, user doesn’t exist, etc
}else{
/*
this part depends on your application. do you use
sessions or access tokens? you need to send the user
something that they can use for authentication on
subsequent requests
*/
res.end(/* send something */);
}
});
}
function authenticate(req,res,next){
/*
read the cookie, access token, etc.
verify that it is legit and then find
the user that it’s associated with
*/
validateRequestAndGetUser(req,function(err,user){
if(err){
next(err); // session expired, tampered, revoked
}else{
req.user = user;
next();
}
});
}
app.post('/login',usernamePasswordExchange);
app.get('/protected-resource',authenticate,function(req,res,next){
/*
If we are here we know the user is authenticated and we
can know who the user is by referencing req.user
*/
});
免责声明:我在 Stormpath 工作,我们花了很多时间写作 身份验证代码 :) 我刚刚编写了我们最新的库,stormpath-sdk-express, 具体实现了我的建议