1

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 Answer 1

3

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. 🍻

Sign up to request clarification or add additional context in comments.

5 Comments

Hello subhamX, I have a question: where should I add the response_type=code ? For what I found out, this could be used as prop in the GoogleLogin component of the react-google-login package, but this way is not available anymore in the component of the @react-oauth/google package. Btw I'm currently testing another method which should be working, if this is the case I'll answer my own question so that you can see how I've done that. Cheers!!
As written in the docs of github.com/anthonyjgrove/react-google-login, there is a responseType prop. You can set code as the value. Although I would prefer to load the google identity script myself and then use const codeClient = window.google.accounts.oauth2.initCodeClient({....}), and codeClient.requestCode(). Refer to official docs for more details.
The problem here is that, as I mentioned in my question, react-google-login is being deprecated because it uses the old google authorization system. react-google-login is being replaced by @react-oauth/google package, which uses the new Google Identity Services SDK as the way to manage authentication and authorization . This new package offers a GoogleLogin component which does NOT have any property to receive the code from the authentication prompt.
@gianlucazani Refer to docs in npmjs.com/package/@react-oauth/google. It's very simple. Just by a quick glance, I could see that there is a hook useGoogleLogin, and you can mention the flow as 'auth-code'.
Yeah that's the way I'm doing the thing now. It seems to work! the only downside is that I cannot use the fancy google button with the logged user printed inside and all that stuff.. but never mind. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.