1

我想从 google auth 获得一封有效的电子邮件,并通过单击使用 google 按钮登录来注册我的用户,这样我就可以获得一个包含用户电子邮件的令牌,如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="google-signin-client_id" content="203772907695-qd52ou2r1bcsht8f515lh63cpqaateq2.apps.googleusercontent.com">
    <script src="https://apis.google.com/js/platform.js" async defer></script>
    <title>Login</title>
</head>
<body>

    <div class="g-signin2" data-onsuccess="onSignIn"></div>

    <script>
    function onSignIn(googleUser) {

        var id_token = googleUser.getAuthResponse().id_token;
        console.log(id_token);
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/login');
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.onload = function() {
            console.log('Signed in as: ' + xhr.responseText);
            if(xhr.responseText == 'success'){
                signOut();
                location.assign('/profile')
            }
        };
        xhr.send(JSON.stringify({token : id_token}));
      }
    </script>
    
</body>
</html>

上面的代码获取token并简单地将其发送到服务器,对吗?

现在在服务器端,我可以使用以下方法记录我们成功发送的客户端令牌console.log(token)

// Google Auth
const {OAuth2Client} = require('google-auth-library');
const CLIENT_ID = '203772907695-qd52ou2r1bcsht8f515lh63cpqaateq2.apps.googleusercontent.com'
const client = new OAuth2Client(CLIENT_ID);

app.post('/login', (req,res)=>{
    let token = req.body.token;
    console.log(token); // gets the token successfully
    // then we should verify that this token is valid not one sent by a hacker right?

})

问题是我们如何验证这token是有效的,而不是黑客发送的?

因为正如您所看到的,黑客可以简单地做我们在客户端所做的事情,并向我们发送一个令牌,就像我们的令牌一样......

我现在这样做的方式是将带有令牌的发布请求发送到此 url:

const response = await axios.post(`https://oauth2.googleapis.com/tokeninfo?id_token=${token}`);
const email = response.data.email;

但这并没有验证任何人都可以发送该令牌并获得类似的结果......

我想通过验证用户发送的令牌来安全地获取用户电子邮件。

4

2 回答 2

0

问题是我们如何验证这个令牌是有效的,而不是由黑客发送的?

黑客无法生成将从 Google API 获取值的有效令牌。


Google 正在使用OpenID Connect(OAuth2.0),它非常安全。简而言之,该过程适合您

  1. 单击使用 Google 登录时被重定向到 google 网站
  2. 您在提供请求的权限后登录那里
  3. 如果您在 Google 控制台中创建的应用程序中的 redirect_uri 数组匹配,Google 在有效登录时会将您返回到重定向 url。
  4. 重定向的 uri 有一个代码查询字符串。IE,code=*****
  5. 在服务器中,您使用代码和 client_secret(客户端不需要)并交换codeaccess_token/id_token

令牌是这样生成的,没有其他任意令牌可以使用 Google API 访问任何 Google 资源。它将返回无效令牌错误

于 2021-07-24T14:02:36.967 回答
0

您可以简单地阅读解释如何做到这一点的文档。这是他们展示的例子:

const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client(CLIENT_ID);
async function verify() {
  const ticket = await client.verifyIdToken({
      idToken: token,
      audience: CLIENT_ID,  // Specify the CLIENT_ID of the app that accesses the backend
      // Or, if multiple clients access the backend:
      //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
  });
  const payload = ticket.getPayload();
  const userid = payload['sub'];
  // If request specified a G Suite domain:
  // const domain = payload['hd'];
}
verify().catch(console.error);
于 2021-07-24T13:41:31.123 回答