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.
refresh_token
only upon the initial request ofaccess_token
, then I must work within these bounds and save it. – Jeff Tanner