为什么缺少 Google OAuth 2.0 随机数

Why is Google OAuth 2.0 nonce missing

我正在尝试在用户使用 google 提示完成登录后验证 JWT。具体来说,我遇到了一个问题,随机数不在 google 发回给我的 JWT 中,正如下面链接文档所预期的那样。

前端代码如下:

<google-login class="ng-isolate-scope">
    <div id="g_id_onload" data-client_id=“********.apps.googleusercontent.com" data-auto_prompt="true" data-nonce=“<randomly generated UUID>" data-login_uri="http://localhost:8080/appName/rest/auth/google/login"></div>
    <div class="g_id_signin" data-type="standard" data-theme="outline" data-text="sign_in_with" data-shape="rectangular" data-logo_alignment="left" data-width="269">
        <div class="S9gUrf-YoZ4jf" style="position: relative;">
            <div></div>
            <iframe src="https://accounts.google.com/gsi/button?type=standard&amp;theme=outline&amp;text=sign_in_with&amp;shape=rectangular&amp;logo_alignment=left&amp;width=269&amp;client_id=******.apps.googleusercontent.com&amp;iframe_id=gsi_86518_300486&amp;as=xHN4SBVSZDA7r8a2zB77gA" id="gsi_86518_300486" title="Sign in with Google Button" style="display: block; position: relative; top: 0px; left: 0px; height: 44px; width: 289px; border: 0px; margin: -2px -10px;"></iframe>
        </div>
    </div>
</google-login>

以及后台验证码

kotlin:
...
    val token: String? = httpServletRequest?.getParameter("g_csrf_token")
    val credential: String? = httpServletRequest?.getParameter("credential")
    val googleUser = GoogleUser().fromToken(token, credential)
java:
public GoogleUser fromToken(String token, String credential){
    GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(
        new NetHttpTransport(), new GsonFactory())
        .setAudience(Collections.singletonList(<my google client id>))
        .build();


    GoogleIdToken verifiedCredential = verifier.verify(credential);
    
    Payload payload = verifiedCredential.getPayload();
    NonceEntity nonceEntity = nonceService.findByNonce(payload.getNonce());
    // payload.getNonce() is null
    ...
}

负载中的所有数据都是我在测试时所期望的,它得到了测试google 帐户名、电子邮件...但是,负载中没有随机数。我从 google 的文档中了解到:https://developers.google.com/identity/protocols/oauth2/openid-connect#an-id-tokens-payload nonce 应该在 google 返回给我的 JWT 中,不是这样吗?

我们将不胜感激,谢谢。

EDIT 1:

在我的浏览器的 'network' 面板中搜索之后,我可以确认随机数已发送到 google,如下所示: https://accounts.google.com/gsi/select?client_id=*******.apps.googleusercontent.com&ux_mode=popup&ui_mode=card&nonce=<my nonce is here>&as=qQuxTPotHkqyksF1xGUJqw&channel_id=11052d41e8597dee7bdca69dee44b56619c612eb4d5618f01defe7458cd6b17f&origin=http%3A%2F%2Flocalhost%3A9000 GET 请求状态 302(重定向)

像这样:

https://accounts.google.com/ServiceLogin?faa=1&rip=1&continue=https://accounts.google.com/gsi/select?client_id%*****.apps.googleusercontent.com%26ux_mode%3Dpopup%26ui_mode%3Dcard%26nonce%<my nonce here>%26as%3DqQuxTPotHkqyksF1xGUJqw%26channel_id%3D11052d41e8597dee7bdca69dee44b56619c612eb4d5618f01defe7458cd6b17f%26origin%3Dhttp://localhost:9000 GET 请求状态 200

它似乎在每个发出的 http 请求中,但在成功登录后不在响应 JWT(凭据)中。

EDIT: 2分辨率: 使用@bdid 提供的代码,我能够得出结论,angular 正在通过 ajax 调用插入数据随机数值,即查找 [=45] 的 google 脚本=] 正在检查 div,因为 ajax 调用的延迟导致随机数出现。

解决方案:我们重写了 .js,以便 google 脚本仅在 ajax 调用完成后添加到页面。这样,就填充了 nonce 值。

或者,我们可以将 nonce 填充移动到控制器并在服务器端解决它,但这是一个更简单的解决方案。

Nonce 应该返回,并且正在我的测试中。可能值得将凭据转储到控制台并将其粘贴到 jwt.io 等在线工具中以快速解码以确认 JWT 是否按预期包含随机数,或者 Kotlin 后端代码是否错误处理随机数。

类似这样的内容将有助于快速确认行为:

<html><body>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script>
        function handleCredentialResponse(response) {
                console.log('JWT ID token, decode me: ' + response.credential);
        };
</script>

<div id="g_id_onload"
     data-client_id="YOUR_CLIENT_ID"
     data-callback="handleCredentialResponse"
     data-nonce="foobar">
</div>
</body></html>

然后解码 response.credential 应该导致 "nonce": "foobar", 作为一个字段包含在有效负载中。