为什么google Oauth verifyIdToken(javascript nodejs版本)不使用客户端密钥?

时间:2016-12-23 16:21:54

标签: node.js google-oauth google-signin google-api-nodejs-client

我正在测试google singin的SPA js + nodejs应用程序。 我添加了这个:

<script src="https://apis.google.com/js/platform.js" async defer></script>

和这些:

<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
<div class="g-signin2" data-onsuccess="onSignIn"></div>

在html5 / js客户端。 遵循本指南:

https://developers.google.com/identity/sign-in/web/sign-in

当用户对库进行身份验证时,获取令牌并将其传递给服务器,如下所述:

https://developers.google.com/identity/sign-in/web/backend-auth

服务器端(nodejs)上的

使用此函数验证令牌:

client.verifyIdToken(
    token,
    CLIENT_ID,
    // Or, if multiple clients access the backend:
    //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3],
    function(e, login) {
      var payload = login.getPayload();
      var userid = payload['sub'];
      // If request specified a G Suite domain:
      //var domain = payload['hd'];
    });

我的问题是:何时使用client_secret?因为我已经使用CLIENT_ID前端从谷歌获取身份验证令牌,所以我使用CLIENT_ID服务器端进行令牌验证。我认为令牌可以使用client_secret(即SECRET)已知的服务器端进行验证,这样其他任何获取令牌的人都无法授权该用户。 我错过了什么?

2 个答案:

答案 0 :(得分:1)

您创建的客户端似乎是公共客户端,客户端密钥用于私人客户端。

编辑:对不起,我使用了术语私人客户端而不是机密客户端。 基本上我们在Oauth2中有两种类型的客户端

  1. 公共客户: - 这些是不需要客户机密的客户。

  2. 私人客户: - 这些客户有客户机密。

  3. 我不能给你一个非常肯定的答案,为什么你没有看到你的客户秘密,因为我之前没有使用这些特定的库,但是 在我看来,你可能创建了一个公共客户而不是一个机密客户。

答案 1 :(得分:0)

我相信我有答案,

查看此处:https://firebase.google.com/docs/auth/admin/verify-id-tokens

它说明了如何自行检查JWT的签名(如果需要),这也是google-auth-library所做的。在库中,在verifySignedJwtWithCertsAsync()中搜索oauth2client.js。 Google在联合登录过程中使用自己的私钥来处理JWT的签名。当JWT返回给您并发送到auth库时,它已经被签名。这很棒,因为您无需触摸私钥。它已安全地存储在Google中,您只需让Google处理该部分即可。然后,当您将JWT发送到服务器时,标头中的密钥ID声明使auth库知道使用哪个公共密钥对其进行解码。如果公钥无法对其进行解码,则说明身份验证失败。

最后,请确保ID令牌已由与该令牌的孩子声明相对应的私钥签名。从https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com中获取公钥,并使用JWT库来验证签名。使用该端点的响应的Cache-Control标头中的max-age值可以知道何时刷新公钥。

如果以上所有验证均成功,则可以将ID令牌的主题(子)用作相应用户或设备的uid。