iOS和node.js:如何验证传递的访问令牌?

26

我有一个使用OAuth和OAuth2提供程序(Facebook、Google、Twitter等)验证用户并提供访问令牌的iOS应用程序。除了最小的数据,如姓名和电子邮件地址之外,该应用程序不会将这些服务用于认证以外的任何事情。

然后,该应用程序将访问令牌发送到服务器以表示用户已通过身份验证。

服务器使用Node.js编写,在执行任何操作之前,它需要根据正确的OAuth*服务验证提供的访问令牌。

我一直在寻找,但到目前为止,我发现的所有node.js身份验证模块似乎都是用于通过服务器提供的网页登录和身份验证。

有没有人知道可以对提供的访问令牌进行简单验证的node.js模块?

4个回答

74
据我所知(并且根据规范的阅读),OAuth和OAuth 2规范没有指定单个访问令牌验证端点。这意味着您需要为每个提供程序编写自定义代码来仅验证访问令牌。
我查找了一下您指定的端点应该怎么做:
Facebook
似乎others使用Facebook的图形API的'me' endpoint来检查令牌是否有效。基本上,请求:
https://graph.facebook.com/me?access_token={accessToken}

谷歌

谷歌为获取访问令牌信息提供了专门的调试端点,并且有良好的文档。基本上,发送请求:

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={accessToken}

然而,他们建议您不要在生产环境中这样做:

用于调试的tokeninfo端点很有用,但是对于生产目的,请从密钥端点检索Google的公共密钥并在本地执行验证。您应该使用jwks_uri元数据值从Discovery document检索密钥URI。对调试端点的请求可能会被限制或受到间歇性错误的影响。

由于Google只偶尔更改其公共密钥,因此您可以使用HTTP响应的缓存指令将它们缓存,并且在绝大多数情况下,通过使用tokeninfo端点进行本地验证比通过检索和解析证书以及进行适当的加密调用来检查签名更加高效。幸运的是,有许多经过良好调试的库可用于各种语言以完成此操作(请参见jwt.io)。

Twitter

Twitter似乎没有一种非常明显的方法来实现这一点。我猜想,由于帐户设置数据相当静态,这可能是验证的最佳方式(获取推文可能具有更高的延迟时间?),因此您可以请求(使用适当的OAuth签名等):
https://api.twitter.com/1.1/account/settings.json

请注意,此API在每个时间窗口内的使用次数受到限制,最多为15次。
总的来说,这似乎比起一开始看起来的要棘手。在服务器上实现某种类型的会话/认证支持可能是一个更好的想法。基本上,您可以验证您获得的外部OAuth令牌一次,然后分配自己的某些会话令牌给用户,通过该令牌在您自己的服务器上对用户ID(电子邮件、FB ID等)进行身份验证,而不是继续为每个请求向OAuth提供程序发出请求。

1
如何在Microsoft和LinkedIn中实现这个? - lincx
@lincx 你知道怎么在领英上做吗? - user968159
这在2018年5月仍然适用吗? - Pavan

3

在生产环境中使用谷歌(google),需要安装 google-auth-library (npm install google-auth-library --save) 并使用以下内容:

const { OAuth2Client } = require('google-auth-library');
const client = new OAuth2Client(GOOGLE_CLIENT_ID); // Replace by your client ID

async function verifyGoogleToken(token) {
  const ticket = await client.verifyIdToken({
    idToken: token,
    audience: GOOGLE_CLIENT_ID  // Replace by your client ID 
  });
  const payload = ticket.getPayload();
  return payload;
}

router.post("/auth/google", (req, res, next) => {
  verifyGoogleToken(req.body.idToken).then(user => {
    console.log(user); // Token is valid, do whatever you want with the user 
  })
  .catch(console.error); // Token invalid
});

更多关于使用后端服务器验证Google令牌的信息。可以找到有关Node.js、Java、Python和PHP示例。

对于Facebook,可以执行https请求,例如:

const https = require('https');

router.post("/auth/facebook", (req, res, next) => {

  const options = {
    hostname: 'graph.facebook.com',
    port: 443,
    path: '/me?access_token=' + req.body.authToken,
    method: 'GET'
  }

  const request = https.get(options, response => {
    response.on('data', function (user) {
      user = JSON.parse(user.toString());
      console.log(user);
    });
  })

  request.on('error', (message) => {
    console.error(message);
  });

  request.end();
})

1

-1

要获取有关从Google使用的令牌的信息,请注意API版本 https://www.googleapis.com/oauth2/v3/tokeninfo?access_token={accessToken}


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