25

我有一个 iOS,它使用 OAuth 和 OAuth2 提供程序(Facebook、谷歌、推特等)来验证用户并提供访问令牌。除了姓名和电子邮件地址等最少的数据外,该应用程序不会将这些服务用于身份验证之外的任何事情。

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

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

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

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

4

4 回答 4

73

据我所知(据我阅读规范可知),OAuth 和 OAuth 2 规范没有为访问令牌验证指定单个端点。这意味着您将需要为每个提供者自定义代码来仅验证访问令牌。

我查找了为您指定的端点执行的操作:

Facebook

似乎其他人已经使用 Facebook 的图形 API 的“我”端点来检查令牌是否有效。基本上,要求:

https://graph.facebook.com/me?access_token={accessToken}

谷歌

谷歌有一个专门的调试端点来获取访问令牌信息,也有很好的文档。基本上,要求:

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

但是,他们建议您不要为生产执行此操作:

tokeninfo端点可用于调试,但出于生产目的,请从密钥端点检索 Google 的公钥并在本地执行验证。您应该使用 jwks_uri 元数据值从发现文档中检索密钥 URI 。对调试端点的请求可能会受到限制或以其他方式受到间歇性错误的影响。

由于 Google 很少更改其公钥,因此您可以使用 HTTP 响应的缓存指令缓存它们,并且在绝大多数情况下,执行本地验证比使用 tokeninfo 端点更有效。此验证需要检索和解析证书,并进行适当的加密调用以检查签名。幸运的是,有多种语言提供的经过良好调试的库可以完成此任务(请参阅 jwt.io)。

推特

Twitter 似乎没有一个非常明显的方法来做到这一点。我怀疑由于帐户设置数据是相当静态的,这可能是最好的验证方式(获取推文可能会有更高的延迟?),因此您可以请求(使用适当的 OAuth 签名等):

https://api.twitter.com/1.1/account/settings.json

请注意,此 API 的速率限制为每个窗口 15 次。

总而言之,这似乎比最初看起来更棘手。在服务器上实现某种会话/身份验证支持可能是一个更好的主意。基本上,您可以验证一次获得的外部 OAuth 令牌,然后为用户分配一些您自己的会话令牌,您可以使用该会话令牌在您自己的服务器上使用用户 ID(电子邮件、FB id 等)进行身份验证,而不是继续制作为您自己收到的每个请求向 OAuth 提供者发出请求。

希望有帮助!

于 2012-09-07T08:43:28.237 回答
2

对于生产环境中的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();
})
于 2021-02-10T18:17:01.067 回答
1

在谷歌的生产中,您可以使用:

https://www.npmjs.com/package/google-auth-library

const ticket = client.verifyIdToken({
    idToken: ctx.request.body.idToken,
    audience: process.env.GOOGLE_CLIENTID
})
于 2020-07-07T13:16:21.487 回答
-1

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

于 2017-01-13T08:04:30.003 回答