如何在 passport-facebook / Passport.js 中捕获 FacebookAuthorizationError?
How to catch FacebookAuthorizationError in passport-facebook / Passport.js?
我有一个 Express 应用程序,它通过 Passport.js 和 passport-facebook 策略使用 Facebook 身份验证。我已遵循 documentation 如何处理身份验证。
一切正常... 直到 Facebook 尝试通过回调Url 报告错误。在这种情况下,我得到一个未捕获的 FacebookAuthorizationError 异常,并且没有调用 failureRedirect。
最终用户看到 "Internal Server Error" 作为未捕获异常的结果,我不遵守 Facebook 开发指南...
Url 导致异常
http://localhost:8081/auth/facebook/callback?error_code=1340031&error_message=Unable+to+Log+In%3A+There+is+a+60-minute+delay+before+new+accounts+can+log+in+to+any+applications.+Please+try+again+in+an+hour.#_=_
异常(截断):
FacebookAuthorizationError: Unable to Log In: There is a 60-minute delay before new accounts can log in to any applications. Please try again in an hour.
at Strategy.authenticate (/Users/Dan/project/node_modules/passport-facebook/lib/strategy.js:81:23)
at attempt (/Users/Dan/project/node_modules/passport/lib/middleware/authenticate.js:361:16)
at authenticate (/Users/Dan/project/node_modules/passport/lib/middleware/authenticate.js:362:7)
at Layer.handle [as handle_request] (/Users/Dan/project/node_modules/express/lib/router/layer.js:95:5)
我读过一篇较早的 post (passport don't redirect to 'failureRedirect' upon failure with facebook),它可能是一个未解决的问题。
我认为这个护照插件会非常受欢迎,并且有人会找到解决方法 - 有人知道吗?
非常感谢。
表达初始化代码:
function initExpress() {
const express = require('express'),
passport = require('passport'),
LocalStrategy = require('passport-local'),
FacebookStrategy = require('passport-facebook').Strategy,
expressSession = require('express-session');
}
let app = express();
app.use(expressSession(
{
secret: secret,
resave: false,
saveUninitialized: false
}
));
app.use(flash());
passport.use(new LocalStrategy(User.authenticate()));
passport.use(new FacebookStrategy({
clientID: process.env.FACEBOOK_APP_ID,
clientSecret: process.env.FACEBOOK_APP_SECRET,
callbackURL: `${process.env.SERVER_API_URL}/auth/facebook/callback`,
profileFields: ['id', 'displayName', 'name', 'picture']
},
function(accessToken, refreshToken, profile, done) {
facebookFindOrCreateUser(accessToken, refreshToken, profile, done);
}
));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
etc..
}
/auth/ 路线:
const express = require('express'),
router = express.Router(),
passport = require('passport');
router.get(
'/facebook',
passport.authenticate('facebook')
);
router.get('/facebook/callback',
passport.authenticate(
'facebook',
{
failureRedirect: '/login',
failureFlash: true
}
),
(req, res) => {
// Successful authentication
res.redirect('/authenticated');
}
);
module.exports = router;
好的,我通过实施中间件错误处理程序解决了这个问题。希望这对某人有用 - 因为我在 passport-facebook 文档中找不到任何关于它的信息。
它捕获之前未捕获的异常并阻止 Express 向最终用户提供的 "Internal Server Error"。
const express = require('express'),
router = express.Router(),
passport = require('passport');
router.get(
'/facebook',
passport.authenticate('facebook')
);
function fbErrorHandler(err, req, res, next) {
// I use flash, but use whatever notification method you want for end users:
req.flash('error', 'Error while trying to login via Facebook: ' + err);
res.redirect('/login');
}
router.get('/facebook/callback',
passport.authenticate(
'facebook',
{
failureRedirect: '/login',
failureFlash: true
},
),
fbErrorHandler,
(req, res) => {
// Successful authentication
res.redirect('/authenticated');
}
);
module.exports = router;
我有一个 Express 应用程序,它通过 Passport.js 和 passport-facebook 策略使用 Facebook 身份验证。我已遵循 documentation 如何处理身份验证。
一切正常... 直到 Facebook 尝试通过回调Url 报告错误。在这种情况下,我得到一个未捕获的 FacebookAuthorizationError 异常,并且没有调用 failureRedirect。
最终用户看到 "Internal Server Error" 作为未捕获异常的结果,我不遵守 Facebook 开发指南...
Url 导致异常
http://localhost:8081/auth/facebook/callback?error_code=1340031&error_message=Unable+to+Log+In%3A+There+is+a+60-minute+delay+before+new+accounts+can+log+in+to+any+applications.+Please+try+again+in+an+hour.#_=_
异常(截断):
FacebookAuthorizationError: Unable to Log In: There is a 60-minute delay before new accounts can log in to any applications. Please try again in an hour.
at Strategy.authenticate (/Users/Dan/project/node_modules/passport-facebook/lib/strategy.js:81:23)
at attempt (/Users/Dan/project/node_modules/passport/lib/middleware/authenticate.js:361:16)
at authenticate (/Users/Dan/project/node_modules/passport/lib/middleware/authenticate.js:362:7)
at Layer.handle [as handle_request] (/Users/Dan/project/node_modules/express/lib/router/layer.js:95:5)
我读过一篇较早的 post (passport don't redirect to 'failureRedirect' upon failure with facebook),它可能是一个未解决的问题。
我认为这个护照插件会非常受欢迎,并且有人会找到解决方法 - 有人知道吗?
非常感谢。
表达初始化代码:
function initExpress() {
const express = require('express'),
passport = require('passport'),
LocalStrategy = require('passport-local'),
FacebookStrategy = require('passport-facebook').Strategy,
expressSession = require('express-session');
}
let app = express();
app.use(expressSession(
{
secret: secret,
resave: false,
saveUninitialized: false
}
));
app.use(flash());
passport.use(new LocalStrategy(User.authenticate()));
passport.use(new FacebookStrategy({
clientID: process.env.FACEBOOK_APP_ID,
clientSecret: process.env.FACEBOOK_APP_SECRET,
callbackURL: `${process.env.SERVER_API_URL}/auth/facebook/callback`,
profileFields: ['id', 'displayName', 'name', 'picture']
},
function(accessToken, refreshToken, profile, done) {
facebookFindOrCreateUser(accessToken, refreshToken, profile, done);
}
));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
etc..
}
/auth/ 路线:
const express = require('express'),
router = express.Router(),
passport = require('passport');
router.get(
'/facebook',
passport.authenticate('facebook')
);
router.get('/facebook/callback',
passport.authenticate(
'facebook',
{
failureRedirect: '/login',
failureFlash: true
}
),
(req, res) => {
// Successful authentication
res.redirect('/authenticated');
}
);
module.exports = router;
好的,我通过实施中间件错误处理程序解决了这个问题。希望这对某人有用 - 因为我在 passport-facebook 文档中找不到任何关于它的信息。
它捕获之前未捕获的异常并阻止 Express 向最终用户提供的 "Internal Server Error"。
const express = require('express'),
router = express.Router(),
passport = require('passport');
router.get(
'/facebook',
passport.authenticate('facebook')
);
function fbErrorHandler(err, req, res, next) {
// I use flash, but use whatever notification method you want for end users:
req.flash('error', 'Error while trying to login via Facebook: ' + err);
res.redirect('/login');
}
router.get('/facebook/callback',
passport.authenticate(
'facebook',
{
failureRedirect: '/login',
failureFlash: true
},
),
fbErrorHandler,
(req, res) => {
// Successful authentication
res.redirect('/authenticated');
}
);
module.exports = router;