From Google JWT to Access and Refresh tokens using React and Node.js

Viewed 41

I have a MERN application and I want to obtain the following behaviour in my app:

  1. A user logs in with with google using the GoogleLogin component in the @react-oauth/google package
  2. After the user logs in and gives permission to my app to access some Google API (e.g. Google Calendar), I want to send the JWT generated from the login process to the Node.js backend
  3. I want to "extract" access and refresh tokens from this JWT (decoding it in some way?)
  4. I want to store the tokens in a persistent way so that I can access the user's calendar whenever I want

I managed to get this done with the GoogleLogin from react-google-login package, which gives you a code that can be exchanged for tokens in the backend. But this library has been recently deprecated (when I try to log in with this button I get this error: idpiframe_initialization_failed). I don't know anymore how to use this library.

This is the code that I use to login:

<GoogleOAuthProvider clientId={"MY_CLIENT_ID"}>
       <GoogleLogin
            onSuccess={this.onSuccess}
            onFailure={this.onFailure}
       />
</GoogleOAuthProvider>;

And this is the object I get when the log in is successful:

{
   clientId: "MY_CLIENT_ID"
   credential: "JWT_string"
   select_by: "btn"
}

I'm not sure this is the right approach to use in order to get access and refresh tokens to use in the backend, or if there's a better way to do so with the new Google Identity Services SDK.

1 Answers

What a coincidence!! I'm currently working on a blog to explain OIDC, OAuth, and the new Google Identity Services, and somehow I saw this question.

let me give a TLDR version to explain different response_type first.

  1. access_token and refresh_token are part of Implicit Flow with response_type=token and Authorization code flow with response_type=code as defined in OIDC 1.0 Core spec.
  2. The JWT (included in "credentials" field of the returned JSON object from Google Server), is Implicit Flow with response_type=id_token.

Here is a small demo link in case you want to play with different auth methods.

I want to "extract" access and refresh tokens from this JWT (decoding it in some way?)

I don't think so. Since id_token was never meant for that purpose.

I want to store the tokens persistently so that I can access the user's calendar whenever I want

I would suggest not using id_token since you need access_token and refresh_token. You can consider the following flow:

  1. Use Authorization code flow with response_type=code to get the code.
  2. Using the code get the refresh_token by making a POST request to https://oauth2.googleapis.com/token. (The response will also contain access_token. Just ignore it.) Or you can also use google-api-nodejs-client library.
  3. Store the refresh token safely.
  4. Make a POST request to https://www.googleapis.com/oauth2/v4/token with the following BODY to get the access_token.
{
    "grant_type": "refresh_token",
    "refresh_token": "YOUR_REFRESH_TOKEN",
    "client_id": "YOUR_VALUE.apps.googleusercontent.com",
    "client_secret": "YOUT_SECRET_VALUE"
}

Do let me know if that helps. Cheers.

Related