React-google-login: Response type "code" sends request for token instead of authorization code

Created on 24 Jan 2021  路  9Comments  路  Source: anthonyjgrove/react-google-login

With the responseType="code" the GoogleAuth.grantOfflineAccess method sends a request for a token. To check that, open the Network tab in the Google Chrome developer tools and login with your account. Here is an example of a request that the GoogleAuth.grantOfflineAccess method does:

https://accounts.google.com/o/oauth2/iframerpc?action=issueToken&response_type=token id_token&login_hint=<login-hint>&client_id=<client-id>&origin=http://localhost:3000&scope=openid profile email&ss_domain=http://localhost:3000

And the response is:

{"token_type":"Bearer",
"access_token":"<access-token>",
"scope":"email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile opened",
"login_hint":"<login-hint>",
"expires_in":3599,
"id_token":"token-id-with-user-info",
"session_state":{"extraQueryParams":{"authuser":"0"}}}

At the same time, the onSuccess callback receives an object with an authorization code only.
I know it's not the react-google-login issue, but still, when you set the responseType to code you expect the access token to never appear on the client site.

Most helpful comment

Just checked my assumption with the gapi.auth2.authorize and it returns the authorization code without setting anything to the session storage or making any additional requests.
It would be nice to have the ability to use react-google-login for authorization only (yes, I know that the name of the library says "google-login" :) )

All 9 comments

I believe the problem is the same as in #337. I _think_ the solution suggested here works, though you need to use your own build.

The reason I'm not certain is that I'm battling with this right now, trying to convert the code in response object (which is all I get) to a valid request to Google API on backend. YMMV.

@anze555 the documentation doesn't state that there is a response_type field in the client config that the gapi.auth2.init accepts. But the react-google-login seems to add some other params that aren't listed in the documentation. So, I assume that the Google JavaScript client may accept some params that aren't listed in the docs.
I'll try that "fix" from the issue and let you know if that is the reason.
May I ask you what problems you have with the backend site?

I can confirm that the fix works, I have managed to get through the rest of the issues.

I mean, as soon as I set responseType to code it statrs opening a popup, even though I have set uxMode to redirect, but I can live with this for now...

The backend issues I had were connected to the redirect_uri I was sending to Google when I wanted to exchange the received code for user authentication token. Whatever I set the redirect_uri to, I got:

{
  "error": "redirect_uri_mismatch",
  "error_description": "Bad Request"
}

It turns out it was just a very stupid error message - technically correct and completely misleading. Instead of using an uri, this parameter has to be set to "postmessage". :roll_eyes:

This request now works:

curl -X POST https://www.googleapis.com/oauth2/v4/token -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=...&client_secret=...&grant_type=authorization_code&code=...&redirect_uri=postmessage"

Hope it helps, enjoy!

@anze555 thanks for sharing your experience!
By the way, what does the postmessage in the redirect_uri means here? It's not documented in Google's docs on the OAuth flow, but I assume it's used to notify the parent window when the authentication on the Google's popup is completed.

I have no idea. I didn't dig any deeper as I have spent way too much time on this detail as it is. If you ever figure it out, do post though, I'm still curious... :)

I don't think that the #337 resolves the issue. The URI is formed correctly, response_type is code. The request that I'm talking about in the description of the issue is performed by the Google JavaScript Client from the original tab that contains the GoogleLogin button.
It seems like the issue is that gapi.auth2.init that is used here performs sign in. Google's library fetches the user's profile and the access_token and stores them in the browser's session storage even if you ask for code only. That is really strange. I ask for an authorization code only, Google's library returns the code only in the callback, but it also makes a request for the access_token in the background for its own purpose.
I guess that using the gapi.auth2.authorize instead of gapi.auth2.init should resolve the issue for the access code and the offline access. I don't want to login a user on the client site when I ask for the authorization code. That's the purpose of the authorization code to perform the login on the backend. While Google's library implicitly stores the user's profile and the access code on the client.

Just checked my assumption with the gapi.auth2.authorize and it returns the authorization code without setting anything to the session storage or making any additional requests.
It would be nice to have the ability to use react-google-login for authorization only (yes, I know that the name of the library says "google-login" :) )

Hi
Do you have an example or some patch to do this ?
Thanks

@sepatin well, my opinion on that is if you need to get the authorization code only then don't use any libraries and just redirect a user to the Google/Facebook sign-in page.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zoripong picture zoripong  路  7Comments

scolyer picture scolyer  路  3Comments

deitas picture deitas  路  8Comments

SSR
rlancer picture rlancer  路  8Comments

rabashani picture rabashani  路  7Comments