简体   繁体   中英

Google OAuth v2.0 generates invalid JWT

We are migrating our existing Javascript Google login to new Google OAuth library, as specified in the deprecation notice here - https://developers.googleblog.com/2021/08/gsi-jsweb-deprecation.html

We are following this guide , and our javascript code looks as follows:

const client = google.accounts.oauth2.initTokenClient({
    client_id: <our-client-id>,
    scope: 'https://www.googleapis.com/auth/userinfo.email \
            https://www.googleapis.com/auth/userinfo.profile',
    callback: (tokenResponse: any) => {
        if (tokenResponse && tokenResponse.access_token) {
            if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
                'https://www.googleapis.com/auth/userinfo.email',
                'https://www.googleapis.com/auth/userinfo.profile')) {
                
                console.log(tokenResponse.access_token );

                .. further auth logic
                 
            }
        }
    }
});
client.requestAccessToken();

Everything works fine in a sense that I am able to retrieve the token from Google, except that it looks like the JWT token generated by the new library is invalid. To be more precise, it does not match the JWT token specification - the token doesn't consist of 3 parts (header/payload/signature) and it's too short (meaning that it probably doesn't carry all the data it should). It also doesn't pass the validation in https://jwt.io/

Let me show you an example.

  1. Token generated by the previous version of the library:

    eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg2MTY0OWU0NTAzMTUzODNmNmI5ZDUxMGI3Y2Q0ZTkyMjZjM2NkODgiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy<...>1MWMifQ.OgOOhbTTbLYzcxNhNdvozf1<...>4bRLT3DILyWeO1FX64WaabGRjCR2amQ

  2. Token generated by the new library:

    ya29.A0ARrdaM_hHsX50Qim6c1NudaZvv6qMpMkbNxW-ltOh49s6U4JKZNvPJV3d0TAE_rqqvkvVG2983ryewiufhdsklKGiH-vEdIs7u2389iwek-dcgkY1SE-b21g0932oiweKT-ZKTJvmHAY

The issue is, therefore, that the new version of the library doesn't return proper JWT token (as described above). We cannot use this new token for anything, since we cannot verify it's integrity (who issued it, whether token secret matches our app id, when the token expires, etc...).

I also try to test this using the Google's own OAuth debug endpoint, but it also complaints that the second token is invalid:

https://oauth2.googleapis.com/tokeninfo?id_token=ya29.A0ARrdaM_hHsX50Qim6c1NudaZvv....

Note: Since JWT bears some private data, I stripped the base64 encoded part of the first token (the part after the first dot and before the second dot), same as the 3rd part (after the second dot). Since I cannot understand the last token, I also replaced some characters in there, but it should not affect the demonstration of this problem.

Has anybody encountered anything like this? We have an existing set of projects that need to be migrated to new JS library but it appears that it simply doesn't work. I tried creating a new project from scratch just to see if the issue is somehow only affecting old projects, but no success - the same broken token is returned by Google OAuth when using the new method.

Google OAuth Access Tokens are not JWTs. They are opaque binary values meaning you cannot directly extract information from the token. Google, however, can look up the token in its systems.

You can verify a Google OAuth Access Token by calling this endpoint:

curl -H 'Authorization: Bearer $ACCESS_TOKEN' https://www.googleapis.com/oauth2/v3/tokeninfo

Additional information for tokens created from user identities:

curl -H 'Authorization: Bearer $ACCESS_TOKEN' https://www.googleapis.com/oauth2/v3/userinfo

If the token is invalid, the request will fail.

The returned information will be JSON describing the token.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM