NodeJS + Express:与范围(访问权限)有关的Passport vs OAuth2

时间:2018-09-07 02:50:41

标签: node.js express oauth-2.0 passport.js oauth2orize

想象一下,我正在 api .example.com上实现API服务,该服务需要使用OAuth2以足够的粒度来容纳其端点以容纳不同的用户类型。

  • 通过Facebook进行身份验证的用户只能访问https:// api .example.com / facebook
  • 通过Twitter进行身份验证的
  • 用户只能访问https:// api .example.com / twitter
  • 根据授权服务在本地进行身份验证的用户可以访问facebook和twitter终结点

这意味着我们具有以下角色:

  • 身份验证提供者(授权服务器,Facebook,Twitter)
  • 授权提供者(我的OAuth2服务器)( auth .example.com)
  • 资源提供者(我的API服务器)( api .example.com)
  • ExpressJS Web应用程序或SPA( www .example.com),或本机应用程序

问题:

第一季度应如何实施应用程序流程?

我的想法是...

Web应用程序必须在会话中将accessToken存储到 api .example.com,并将会话ID发送到Web浏览器。如果没有accessToken,它必须将浏览器重定向到 auth .example.com / login / selectprovider /,并提供client_id =“ www .example.com”和client_secret ,以及redirect_url =“ https:// www .example.com /”。

在https:// auth .example.com / login / selectprovider /上,用户选择facebook或twitter或local,然后 auth .example.com重定向用户(再次)使用client_id和client_secret和redirect_url = https:// auth .example.com / twitter 或https:// < strong> auth .example.com / 推特以轻松区分这三个。

Facebook / twitter / local方法将对用户进行身份验证,并将浏览器重定向回 auth .example.com。

然后

auth .example.com将为 api .example.com生成(承载)accessToken,并将其与user.id一起存储到本地数据库表中并关联范围(“ facebook”,“ twitter”或“ local”),将密钥(userId)放在浏览器会话中,然后重定向到https:// www .example.com /

现在,当用户单击WebApp中的链接时, www .example.com在 api .example.com上执行GET或POST,并提供client_id =“ www.example.com” client_secret和access_token。

api .example.com端点验证accessToken,如果可以,执行API并将值返回到 www .example.com,以将其呈现到用户的浏览器。

Q2 是否在正确的流程之上,或者有更好的方法吗? 如果正确, api .example.com如何在其端点上验证accessToken?

应该 auth .example.com为此公开一个特殊的终结点(例如/ userinfo),该终结点只能通过client_id =“ api .example.com访问”和client_secret?每次通话似乎很昂贵,但是 api .example.com还能如何信任令牌的有效性(因为令牌已过期或用户注销)?

什么是OAuth2标准兼容方式?

第三季度在“ passport / OAuth2orize”示例中,我看到了验证身份验证的三种方式:

  • 如果(要求用户){...};
  • if(req.isAuthenticated()){...};
  • passport.authenticate('bearer',{session:false);

第四季度,passport.authenticate('facebook')到底能做什么?

此信息在策略中提供。

passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, cb) {
    User.findOrCreate({ facebookId: profile.id }, function (err, user) {
        return cb(err, user);
    });
  }
));

因此它包含client_id和client_secret。什么时候使用?每次调用password.authenticate('facebook')时?是否整个重定向到Facebook登录页面,是否获得了授权代码许可并将其交换为accessToken,以某种方式在内部存储了AccessToken并保持其注销状态?

这似乎不太可能,但我不知道在没有所有这些的情况下它如何才能真正验证用户身份。而且对于每个API调用而言,这样做都太昂贵了,所以我确信它可以更有效地工作。但是我不知道怎么做,对源代码的研究并没有使它更加清晰。

Q5 .example.com如何知道每个API请求中 www .example.com包含的Bearer accessToken没有被伪造或过期?

我认为它必须对照 auth .example.com服务进行检查,并且该服务又必须检查facebook / twitter会话是否仍然仍然有效,并使用refreshToken刷新令牌。在那一刻?

0 个答案:

没有答案