YouTube API refresh token revoked with 400 code “invalid_grant” (for seemingly no reason)

2,592 views
Skip to first unread message

Jasper Palfree

unread,
Oct 19, 2012, 1:05:13 PM10/19/12
to oauth...@googlegroups.com

I originally posted this on StackOverflow (I'd appreciate an answer there if you can): http://stackoverflow.com/questions/12784816/youtube-api-refresh-token-revoked-with-400-code-invalid-grant-for-seemingly-n

I've built a server-side PHP application that involves reading/making changes to one users's YouTube account (changes to caption files). The user is authenticated with OAuth 2. I have been storing the refresh_token and making refresh requests successfully when the access_token expires.

But now, I seem to be getting an error, which coincidentally correlates with two things:

  • User's upload of a new video
  • Sunday nights

I don't know if that means anything.

The error happens when trying to refresh the access token and I'm using the same way of refreshing the token as I have previously. Here are the details:

Error message:

[status code] 400
[reason phrase] Bad Request
[url] https://accounts.google.com/o/oauth2/token
[request] POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
User-Agent: Guzzle/2.8.6 curl/7.24.0 PHP/5.3.10
Content-Type: application/x-www-form-urlencoded

client_id=442147492209.apps.googleusercontent.com&client_secret=D7eLQ5b0Mo1Y8uZ30ReWYwls&grant_type=refresh_token&refresh_token=1%2FCLvAt8V_d9sZznpg5YZdJlOJ58ufbHKL4F5Lw8PiJOg
[response] HTTP/1.1 400 Bad Request
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Date: Tue, 02 Oct 2012 16:28:24 GMT
Content-Type: application/json
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Transfer-Encoding: chunked

{
  "error" : "invalid_grant"
}

If you feel like looking at the source code, it's on github. Here's the relevant line number where refresh takes place: https://github.com/wellcaffeinated/yt-subtitle-explorer/blob/master/app/YTSE/OAuth/LoginManager.php#L330

(You'll notice that I've added a check for this error and ask the administrator to reauthorize the application... but this is far from ideal)

Other posts I've looked into were telling people to use approval_prompt=force... so I am doing that.

My newest suspicion is that since I am requesting offline access (approval_prompt=force) every time the administrator logs in, I keep generating new refresh_tokens (which I don't record unless no others are available). Does google's OAuth have a maximum number of "active" refresh_tokens per application? Or something like that?

Thanks!

Jasper Palfree

unread,
Nov 2, 2012, 9:49:44 PM11/2/12
to oauth...@googlegroups.com
Really no ideas?
Can I give any more information? The problem still exists and is really annoying...

Rajat

unread,
Nov 23, 2012, 1:34:30 AM11/23/12
to oauth...@googlegroups.com
I am also faced with the same problem, wondering what to do now? :(

Breno de Medeiros

unread,
Nov 26, 2012, 11:24:28 AM11/26/12
to oauth...@googlegroups.com

I don't know of any reason why you should be seeing errors on a periodic basis. However requiring new refresh token on every login will cause older refresh tokens to expire after a threshold has been reached. Ideally you should only use prompt=force when you have to recover from rare events such as loss of refresh token.

--
 
 

Mark Dedere

unread,
Dec 3, 2012, 2:31:46 PM12/3/12
to oauth...@googlegroups.com
Why not refresh before the token expires? Try the api call
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.AHES6ZQken0NVWVXr1iCoWUAoybOcEjBD5D3gwKMxxxxxx
and check the expire value and refresh shortly before the current token becomes invalid.

The API call retrieves following information in JSON format:
{
 "issued_to": "820660xxxxxx.apps.googleusercontent.com",
 "audience": "820660xxxxxx.apps.googleusercontent.com",
 "scope": "http://spreadsheets.google.com/feeds/ https://docs.google.com/feeds/ https://www.googleapis.com/auth/drive.file https://spreadsheets.google.com/feeds/",
 "expires_in": 3167,
 "access_type": "offline"
}

By the way in the docs are no consistent descriptions how excact to handle the refresh.
In the chapter [1] "Installed Apps" is no hint for check for 4xx errors in opposite
to chapter [2] "Devices". I suppose there is possibly a lack in the implementation after
a token is expired. How long will a refresh token last to generate a new access token?
That's completely unclear and maybe a security issue...



[1] https://developers.google.com/accounts/docs/OAuth2InstalledApp#refresh
[2] https://developers.google.com/accounts/docs/OAuth2ForDevices#obtainingatoken



Kind Regards, Mark

Jasper Palfree

unread,
Dec 3, 2012, 2:49:24 PM12/3/12
to oauth...@googlegroups.com
Thanks Mark, but the refresh call is the problem, and it's what's giving the 400 code.

It might be due to the 25 upper limit mentioned... i'm checking it out to see if that's causing it.

Cheers,
-Jasper



--
 
 

Reply all
Reply to author
Forward
0 new messages