如何在 passport-facebook / Passport.js 中捕获 FacebookAuthorizationError?

Posted

技术标签:

【中文标题】如何在 passport-facebook / Passport.js 中捕获 FacebookAuthorizationError?【英文标题】:How to catch FacebookAuthorizationError in passport-facebook / Passport.js? 【发布时间】:2020-05-27 19:46:20 【问题描述】:

我有一个快速应用程序,它通过 Passport.js 和 passport-facebook 策略使用 Facebook 身份验证。我已经关注了documentation 如何处理身份验证。

一切正常... 直到 Facebook 尝试通过回调 URL 报告错误。在这种情况下,我得到了一个未捕获的 FacebookAuthorizationError 异常,并且没有调用 failureRedirect。

由于未捕获的异常,最终用户会看到“内部服务器错误”,并且我不遵守 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)

我读过一篇较早的帖子 (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;

【问题讨论】:

【参考方案1】:

好的,我通过实现中间件错误处理程序解决了问题。希望这对某人有用-因为我在passport-facebook文档中找不到任何有关它的信息。

它会捕获先前未捕获的异常并防止 Express 提供给最终用户的“内部服务器错误”。

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;

【讨论】:

以上是关于如何在 passport-facebook / Passport.js 中捕获 FacebookAuthorizationError?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 客户端中处理 passport-facebook 回调?

如何在没有会话的情况下整合passport-facebook和jwt?

如何使用passport-facebook身份验证重定向到用户登录react-redux应用程序的页面?

Facebook 登录在用户个人资料中返回“未定义”字段,并且不返回电子邮件。 MEANJs + Passport-facebook

Passport-facebook没有收到电子邮件[重复]

passportJS - passport-facebook 无法获取失败重定向路由