如何在 PassportJS/Express 内出错后重定向?
How to redirect after error inside of PassportJS/Express?
使用 Express 和 NodeJS 配置护照时,如果用户的电子邮件地址无效,我将抛出错误。出现此错误后,我想重定向到一个失败页面,向他们提供有关如何正确登录的说明。有没有更好的方法来做到这一点?如果没有,我将如何以某种方式捕获错误并重定向到新页面。
passport.use(new GoogleStrategy({
clientID : auth.googleAuth.clientID,
/* Settings redacted for brevity */
},
function(token, refreshToken, profile, done) {
User.findOne(
{
"google.id" : profile.id
},
function(err, user) {
if (err) return done(err)
if (user) return done(null, user)
else {
if (email.indexOf("lsmsa.edu") > -1) {
// Code redacted for brevity
} else {
done(new Error("Invalid email address"))
}
}
}
)
}))
注意:我也很喜欢 BlackMamba 的回答,添加自定义回调/重定向是一个完全可以接受的选项。
只需将您自己的错误处理中间件添加到 Express:
passport.use(new GoogleStrategy({
clientID : auth.googleAuth.clientID,
/* Settings redacted for brevity */
},
function(token, refreshToken, profile, done) {
User.findOne({
"google.id" : profile.id
},
function(err, user) {
if (err) return done(err)
if (user) return done(null, user)
else {
if (email.indexOf("lsmsa.edu") > -1) {
} else {
// Throw a new error with identifier:
done(throw {
type: "invalid_email_address",
code: 401,
profileId: profile.id
}));
}
}
}
)
}));
// The error handling middleware:
app.use(function(e, req, res, next) {
if (e.type === "invalid_email_address") {
res.status(e.code).json({
error: {
msg: "Unauthorized access",
user: e.profileId
}
});
}
});
您会注意到我用更稳健的错误组合稍微修改了这个答案。我定义了错误的 code
属性 以匹配适用的 HTTP 状态代码——在本例中,401
:
// callback
done(throw {
// just a custom object with whatever properties you want/need
type: "invalid_email_address",
code: 401,
profileId: profile.id
}));
在错误处理中,我们简单地检查类型是 invalid_email_address
(你可以随意设置它,但它应该在你的应用程序中保持一致)然后使用 [=29 写出错误=] 作为 HTTP 状态代码:
// e is the error object, and code is the custom property we defined
res.status(e.code).json({
error: {
msg: "Unauthorized access",
user: e.profileId
}
});
这是一个带有重定向的独立工作示例:
var express = require('express');
var app = express();
app.all('*', function(req, res) {
throw {type: "unauthorized", code: 401}
})
app.use(function(e, req, res, next) {
console.log(e);
if (e.code === 401) {
res.redirect("/login")
} else {
res.status(500).json({error: e.type});
}
});
app.listen(9000);
我想你可以用这个:
Redirects
A redirect is commonly issued after authenticating a request.
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login' }));
In this case, the redirect options override the default behavior. Upon
successful authentication, the user will be redirected to the home
page. If authentication fails, the user will be redirected back to the
login page for another attempt.
或者这样:
Custom Callback
If the built-in options are not sufficient for handling an
authentication request, a custom callback can be provided to allow the
application to handle success or failure.
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
使用 Express 和 NodeJS 配置护照时,如果用户的电子邮件地址无效,我将抛出错误。出现此错误后,我想重定向到一个失败页面,向他们提供有关如何正确登录的说明。有没有更好的方法来做到这一点?如果没有,我将如何以某种方式捕获错误并重定向到新页面。
passport.use(new GoogleStrategy({
clientID : auth.googleAuth.clientID,
/* Settings redacted for brevity */
},
function(token, refreshToken, profile, done) {
User.findOne(
{
"google.id" : profile.id
},
function(err, user) {
if (err) return done(err)
if (user) return done(null, user)
else {
if (email.indexOf("lsmsa.edu") > -1) {
// Code redacted for brevity
} else {
done(new Error("Invalid email address"))
}
}
}
)
}))
注意:我也很喜欢 BlackMamba 的回答,添加自定义回调/重定向是一个完全可以接受的选项。
只需将您自己的错误处理中间件添加到 Express:
passport.use(new GoogleStrategy({
clientID : auth.googleAuth.clientID,
/* Settings redacted for brevity */
},
function(token, refreshToken, profile, done) {
User.findOne({
"google.id" : profile.id
},
function(err, user) {
if (err) return done(err)
if (user) return done(null, user)
else {
if (email.indexOf("lsmsa.edu") > -1) {
} else {
// Throw a new error with identifier:
done(throw {
type: "invalid_email_address",
code: 401,
profileId: profile.id
}));
}
}
}
)
}));
// The error handling middleware:
app.use(function(e, req, res, next) {
if (e.type === "invalid_email_address") {
res.status(e.code).json({
error: {
msg: "Unauthorized access",
user: e.profileId
}
});
}
});
您会注意到我用更稳健的错误组合稍微修改了这个答案。我定义了错误的 code
属性 以匹配适用的 HTTP 状态代码——在本例中,401
:
// callback
done(throw {
// just a custom object with whatever properties you want/need
type: "invalid_email_address",
code: 401,
profileId: profile.id
}));
在错误处理中,我们简单地检查类型是 invalid_email_address
(你可以随意设置它,但它应该在你的应用程序中保持一致)然后使用 [=29 写出错误=] 作为 HTTP 状态代码:
// e is the error object, and code is the custom property we defined
res.status(e.code).json({
error: {
msg: "Unauthorized access",
user: e.profileId
}
});
这是一个带有重定向的独立工作示例:
var express = require('express');
var app = express();
app.all('*', function(req, res) {
throw {type: "unauthorized", code: 401}
})
app.use(function(e, req, res, next) {
console.log(e);
if (e.code === 401) {
res.redirect("/login")
} else {
res.status(500).json({error: e.type});
}
});
app.listen(9000);
我想你可以用这个:
Redirects
A redirect is commonly issued after authenticating a request.
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login' }));
In this case, the redirect options override the default behavior. Upon successful authentication, the user will be redirected to the home page. If authentication fails, the user will be redirected back to the login page for another attempt.
或者这样:
Custom Callback
If the built-in options are not sufficient for handling an authentication request, a custom callback can be provided to allow the application to handle success or failure.
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});