电子邮件字段在passport.js Facebook策略中是可选的 [英] email field is optional in passportjs facebook strategy

查看:123
本文介绍了电子邮件字段在passport.js Facebook策略中是可选的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了用于登录Facebook的代码,一切正常,我正在获取用户的电子邮件地址.但是facebook上还有另一个选项,可让用户选择我的应用程序将有权访问的数据.

I wrote the code for login with facebook, everything works and I'm getting the user's email address. But there is another option on facebook which lets the user select the data my application is going to have access to.

如果用户单击该名称,则会看到名称和所有标记为必填项,但是电子邮件是可选的,用户可以将其从将要提供给应用程序的数据中删除.

If user clicks on that, he'll see the name and everything marked as required, but email is optional and the user can remove it from the data that is going to be provided to the app.

在应用程序上,电子邮件是必需的.那么如何在Facebook上按要求标记电子邮件?

On the application, email is required. So how I can mark the email as required on facebook?

这是我在代码中使用的代码段.

This is the snippet I'm using in the code.

passport.use(new FacebookStrategy({
        clientID: config.social.facebook.clientID,
        clientSecret: config.social.facebook.clientSecret,
        callbackURL: config.url+'auth/facebook/cb',
        enableProof: false,
        profileFields:['id', 'name', 'emails'],
        scope: "email"
    }, function(accessToken, refreshToken, profile, done) {
        // doing the rest of the thing
    }
));

// ...

app.get('/auth/facebook', passport.authenticate('facebook', {scope: ['email']}));
app.get('/auth/facebook/cb', passport.authenticate('facebook'), function(req, res, next) {
    res.redirect("/");
});

推荐答案

我通过重新请求权限解决了该问题.

I solved the problem by re-requesting the permission.

结果是我可以将authType: 'rerequest'添加到passport.authenticate('facebook', {scope: ['email'], authType: 'rerequest'}).

Turns out I can add authType: 'rerequest' to passport.authenticate('facebook', {scope: ['email'], authType: 'rerequest'}).

我要做的是检查结果中是否存在emails字段,如果不存在,我会错误地调用done.

What I did is to check if the emails field is present in the result, if not, I call done with an error.

function(accessToken, refreshToken, profile, done) {
    if (profile.emails === undefined) {
        done('email-required')
        return;
    }
    // doing the rest of the thing
}

然后要捕获错误,我不得不为passport.authenticate('facebook')写一个自定义回调.

Then to catch the error, I had to write a custom callback for passport.authenticate('facebook').

app.get('/auth/facebook/cb', function(req, res, next) {
    passport.authenticate('facebook', function (err, user, info) {
        if (err) {
            if (err == 'email-required') res.redirect('/auth/facebook/rerequest');
            // check for other kinds of errors and show proper messages
            return;
        }
        req.user = user;
        // do the rest of the thing
    })(req, res, next)
});

如您所见,如果发生错误,我会将用户重定向到另一条路由/auth/facebook/rerequest.

As you see, I redirect the user to another route /auth/facebook/rerequest in case of error.

app.get('/auth/facebook/rerequest',
    passport.authenticate('facebook', {
        scope: ['email'],
        authType: 'rerequest' // this is important
    }
));

这将再次将用户重定向到FB上的同一页面,并且这次需要电子邮件字段.我不能在同一条路线上做到这一点;显然,它使用的是相同的生成代码来与fb通信,而fb无法接受.

This will redirect the user to the same page on FB again and this time email field is required. I couldn't do this in the same route; apparently it was using the same generated code to communicate to fb which was not acceptable by fb.

这就是我设法解决此问题的方式.

And that's how I managed to solve the issue.

这篇关于电子邮件字段在passport.js Facebook策略中是可选的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆