0
votes

Problem

I am perplexed when refreshing an access_token with a previous acquired refresh_token does not return a new refresh_token.

Google OAuth 2.0 Steps

Request authentication_code

The following URL, opened in default browser, is requesting authentication code, with access_type=offline to return refresh_token applying returned code to retrieve access_token:

https://accounts.google.com/o/oauth2/v2/auth?
access_type=offline
&prompt=consent
&response_type=code
&client_id=[** CLIENT_ID **]
&redirect_uri=http://localhost
&state=[** STATE **]
&scope=https%3a%2f%2fwww.googleapis.com%2fauth%2fuserinfo.email%20https%3a%2f%2fwww.googleapis.com%2fauth%2fuserinfo.profile%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive

Parse redirect_uri for authentication_code

The query string properties of the returned redirect_uri=http://localhost are parsed as follows:

{
  "state": "[** STATE **]",
  "code": "[** AUTH CODE **]",
  "scope": "email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive openid",
  "authuser": "1",
  "hd": "[** HOST DOMAIN **]",
  "prompt": "consent",
  "session_state": "[** SESSION STATE **]"
}

Request access_token using authentication_code

Using returned [** AUTH CODE **], request access_token and refresh_token:

curl "https://www.googleapis.com/oauth2/v4/token" \
--request POST \
--silent \
--data 'grant_type=authorization_code
  &code=[** AUTH CODE **]
  &client_id=[** CLIENT_ID **]
  &client_secret=[** CLIENT_SECRET **]
  &redirect_uri=http://localhost
  &state=[** STATE **]'

Response includes both access_token and refresh_token:

{
  "access_token": "[** ACCESS_TOKEN  **]",
  "expires_in": 3599,
  "refresh_token": "[** REFRESH_TOKEN  **]",
  "scope": "openid https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile",
  "token_type": "Bearer",
  "id_token": "[** TOKEN ID **]"
}

Refresh access_token using refresh_token

Next testing out refresh_token to refresh access_token:

curl "https://www.googleapis.com/oauth2/v4/token" \
--request POST \
--verbose \
--connect-timeout 60 \
--silent \
--data 'grant_type=refresh_token
  &client_id=[** CLIENT_ID **]
  &client_secret=[** CLIENT_SECRET **]
  &refresh_token=[** REFRESH_TOKEN  **]'

Response includes access_token but not refresh_token:

{
  "access_token": "[** ACCESS_TOKEN  **]",
  "expires_in": 3599,
  "scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive openid",
  "token_type": "Bearer",
  "id_token": "[** TOKEN ID **]"
}

Save refresh_token?

However, it appears that if I reuse the initially provided refresh_token=[** REFRESH_TOKEN **], it is still good in refreshing access_token indefinitely.

Therefore, it seems refresh_token=[** REFRESH_TOKEN **] must be stored after the initial consent, which is odd for OAuth 2.0 service.

Previous Posting

There was a previous Stack Overflow posting in March 2015: Google OAuth 2.0 Refresh Token

To get a new refresh token for your client you first need to revoke the existing/old refresh token by revoking access for your client in the Account Permissions tab for your Google account and then ask for access_type=offline again.

In other OAuth 2.0 services, a new refresh_token is provided every time a refresh request is performed, and does not require going to

Summary

Is there any other way to get a new refresh_token every time it is used to a get a new access_token? Other OAuth 2.0 solutions are not so complicated in handling refresh.

Thank you, appreciate any response.

1
Unfortunately, in the current stage, at Google's OAuth2, there are no methods for retrieving the refresh token using the refresh token. Can I ask you about the reason that you are required to retrieve the refresh token using the refresh token? And, in your case, for example, how about using the service account? In this case, the access token can be directly retrieved without the process for retrieving the authorization code. If this was not the direction you want, I apologize.Tanaike
@Tanaike Thank you for your reply. I have found that since this is the way Google OAuth 2.0 provides a refresh_token only upon the initial request of access_token, then I must work within these bounds and save it.Jeff Tanner

1 Answers

0
votes

Since the initially provided refresh_token is valid indefinitely in refreshing an access_token and it works, okay then.