【问题标题】:How to properly verify the integrity of a Google token?如何正确验证 Google 令牌的完整性?
【发布时间】:2015-09-29 13:06:11
【问题描述】:

我正在尝试通过用户的 Google 帐户安全地登录用户。 我正处于使用thiscordova 插件检索用户ID 和oAuthToken 的阶段。

现在我需要将这些凭据发送到我的服务器,然后在服务器端验证令牌的完整性。本质上,我正在尝试执行this 过程的一部分。

我对应该尝试使用 Google 客户端 api 验证哪个令牌感到困惑。我应该使用 userID 还是 oAuthToken ?

文档提到验证用户 ID,但我觉得这很奇怪。这是否意味着如果有人获得我的用户 ID,他们基本上可以闯入我的服务器?用户 id 永远不会改变(如果我在这里错了,请纠正我),因此对此进行验证似乎不安全。验证设置为 expire 的 oAuthToken 不是更有意义吗?还是用户ID也过期了?

欢迎任何建议。

谢谢,

菲多

编辑:

对于任何有兴趣的人。我的困惑是由于不完全理解 google api 可以返回的三个令牌:userId、oAuthToken 和 idToken。 简而言之:userId 与大多数识别用户的 api 调用一起返回。这似乎是恒定的。当我作为 Android 客户端访问 google api 时,我的案例中的 oAuthToken 被返回。以 web 客户端访问 api 时返回 tokenId。因此,那些希望使用移动检索到的令牌进行服务器端验证的人应该作为 Web 客户端访问 api。然后可以使用类似于下面接受的答案的代码在服务器端验证返回的令牌。

【问题讨论】:

    标签: android oauth google-signin


    【解决方案1】:

    您需要验证 IdToken,切勿在开放线上发送 userId。 IdToken 很快就会过期,并且几乎无法破解暴力模拟攻击。

    这个 php sn-p 接收一个以 idtoken= 开头的 HTTP 请求,验证您的令牌服务器端并返回完整的数组或用户电子邮件:

    <?php
    $inputRaw =  file_get_contents('php://input');
    $idToken= substr($inputRaw,8);
    $fp = fopen('twoStepOutput.txt', 'a');
    
    $url = 'https://www.googleapis.com/oauth2/v3/tokeninfo?id_token='.$idToken;
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    $json = json_decode($response, true);
    curl_close($ch);
    
    $userEmail = $json["email"];
    $clientId = $json["azp"];
    //fwrite($fp, date("YmdHis")."\r\n$idToken\r\n");
    fwrite($fp, date("YmdHis")."\r\n");
    fwrite($fp, "email Confirmed by GOOGLE:[$userEmail]\r\n");
    //print_r($json); // returns array console readable
    print_r($clientId); // returns google client id for verification (without transfering user data)
    fclose($fp);
    ?>
    

    以防万一您有疑问,这是 IdToken 的样子:

    eypZCI6OiJSUzI1JhbGciNiIsImtIjk4MzQxMzgyMWJmMzhiNTJlM4OTI2YTllMTc0YTc5MWMwNGMifQ.eyJpc3MiOi3VizExYJhY2NvdW50cy5nb29nbGUuY29tIiwicmEIjoiMTAzNDUyNjAwODM5NzY3MjU2MDE0IiwiYXpwIjoiMTA3OTMxMTEyNTc1OS1lYWJhbWV0b2ZldjIwY28zbGQ5b2o1YWQwMzFuZG9nMC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImVtYWlsIjoidG9ueWdpbGJyQGdtYWlsLmNvbSIsImF0X2hhc2giOiJaSkhxbUZHcnR5Y29kdEhhOGJvMEYWY1NTk2NzUsImV4cCVBIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF1ZCI6IjEwNzkzMTExMjU3NTkt1ldG9mZXYyMGNvM2xkOW9qNWFkMDMxbmRvZzAuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJpYXQiOjE0MzZWFiI6MTQzNjU2MzI3NSwibmFtZSI6IlRvbnkgR2lsIiwicGljdHVyZSI6Imh0dHBzOi8vbGg0Lmdvb2dsZXVzZXJjb250ZW50LmNvbS8tQVREckRSbF9UdFEvQUFBQUFBQUFBQUkvQUFBQUFBQUFBRncvOVdDQnZkYlpUTEEvczk2LWMvcGhvdG8uanBnIiwiZ2l2ZW5fbmFtZSI6IlRvbnkiLCJmYW1pbHlfbmFtZSI6IkdpbCIsImxvY2FsZSI6ImVuIn0.L4peW11TD0bDOlvYKNY60ieZ1sbZfW9gEImcuxVA5f9U_4N49Io1CFXoGKmEPR_ij4q38tF2drPMOKijQePwlrxDui37ubzAdVkuksCJUobzjD1_eccF_8GldP5Y1_XsU8xrZeEnfabfiYpr-VwoLzIeNNUdy9SUbUWjMHNcvf4dGFMzE_SONHr57igjHK3rGkbvLo-UduFngm3e-EL0YR2zOKOVj1Qs8g8_qpWgkn8XABTme1thmuU8OfC-HaF9_B2Zk2UCsnOu4ApiYZk3DPIKgeX6AF11kYnzgvciYheWeddly0foT4G00C7w_wgtd-LSRw0XZltec_MPMa2QSA

    【讨论】:

    • 感谢@tony-gil 的澄清。我使用了错误的验证类型。我使用的是 Andoird 客户端,但由于我的应用程序是 cordova 构建的,它应该是一个 Web 客户端。这就是为什么我对 userId、oAuthToken 和 tokenId 感到困惑。所有 3 个都不同,后者仅通过在 Google Developer 控制台上创建 Web 客户端来显示。
    • 尝试使用 google 的 php 客户端 API 执行此操作几个小时,但没有成功。这是第一次尝试! +1
    • tks @SkeetsO'Reilly!在我发现这一点之前,我花了数周的时间把头撞在墙上。谷歌不擅长的一件事是技术信息分发。这应该在 API 101 中以粗体大字显示。
    猜你喜欢
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2012-12-23
    相关资源
    最近更新 更多