Passport.js:passport-facebook-token策略,通过JS SDK登录,然后验证护照?

24
我正在寻找一种方法,让我的客户使用Facebook JS SDK进行授权,然后将此授权转移到我的节点服务器上(以便它可以使用fb graph api验证请求)。我偶然发现了这个链接:https://github.com/jaredhanson/passport-facebook/issues/26

&

https://github.com/drudge/passport-facebook-token

这似乎是与passport-facebook完全不同的策略。

我猜想,使用fb JS SDK登录后,facebook-token策略从文档或body对象中提取令牌和fb id?

还是有其他更好的方法来实现这一点?我正在尝试避免服务器SDK强制执行的重定向。


经过一些调查,我认为req.body.accessToken需要由客户端设置,然后才能被passport-facebook-token捕获? - matthiasdv
1个回答

41

本周我花了几天时间研究如何最佳地使用Facebook身份验证来保护私有API,使用passport.js - passport-facebook-token就非常适合这个需求。

你的想法是正确的,这确实是两种不同的身份验证策略,你无需安装passport-facebook即可使用passport-facebook-token。

如果你已经在客户端JS(或iOS等)中实现了Facebook身份验证,并且正在寻找一种方法来使用用户的Facebook authToken对API请求进行身份验证,那么passport-facebook-token是一个非常优雅的解决方案。

passport-facebook-token完全独立于passport-facebook工作,基本上在内部处理Facebook所需的重定向,然后将请求传递给你的控制器。

因此,要使用passport-facebook-token对API路由进行身份验证,你需要设置一个像下面这样的passport策略:

passport.use('facebook-token', new FacebookTokenStrategy({
    clientID        : "123-your-app-id",
    clientSecret    : "ssshhhhhhhhh"
  },
  function(accessToken, refreshToken, profile, done) {
    // console.log(profile);

    var user = {
        'email': profile.emails[0].value,
        'name' : profile.name.givenName + ' ' + profile.name.familyName,
        'id'   : profile.id,
        'token': accessToken
    }

    // You can perform any necessary actions with your user at this point,
    // e.g. internal verification against a users table,
    // creating new user entries, etc.

    return done(null, user); // the user object we just made gets passed to the route's controller as `req.user`
  }
));

值得注意的是,在passport-facebook-token的自述文件中使用的User.findOrCreate方法不是默认的mongo/mongoose方法,而是一个插件,如果您想使用它,您需要安装它。

要将此身份验证策略用作任何路由的中间件,您需要将一个access_token对象作为URL参数或作为请求正文的属性传递给它。

app.get('/my/api/:access_token/endpoint', 
        passport.authenticate(['facebook-token','other-strategies']), 
        function (req, res) {

            if (req.user){
                //you're authenticated! return sensitive secret information here.
                res.send(200, {'secrets':['array','of','top','secret','information']});
            } else {
                // not authenticated. go away.
                res.send(401)
            }

        }

注意,access_token属性是大小写敏感的,并且使用下划线。 passport-facebook-token的文档不够详细,但源代码注释良好,非常易读,因此我鼓励您自己去看看。这确实有助于我理解passport的一些更通用的工作方式。


“/my/api/:auth_token/endpoint” 应该改为 “/my/api/:access_token/endpoint” 吧? - smukov
@smukov,你说得完全正确!我已经编辑了答案以反映这个更正,谢谢! - Orangetronic
@Orangetronic 我一直在使用这个中间件,发现了一些奇怪的问题。即使我使用错误的客户端ID和客户端密钥,我仍然能够获取客户端详细信息。更多信息请参见https://github.com/drudge/passport-facebook-token/issues/65 - rakesh kashyap
当我从Postman发起调用时,我收到了未经授权的错误。链接http://stackoverflow.com/q/43557408/1939163 - Luzan Baral
@AbhishekSaini 可能会是这样! - Orangetronic
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接