Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to refresh access token : response is "unauthorized_client"

Tags:

I am getting an error when I try to refresh access token:

400 Bad Request

{error : "unauthorized_client"}

From the Google token URI:

{   "error" : "invalid_request" } 

I read this answer here and the official Google documentation (which describes how a POST request should look) and I don't see any difference.

I captured my POST request (secrets removed):

POST /SHOWMERAWPOST HTTP/1.1 User-Agent: Google-HTTP-Java-Client/1.10.3-beta (gzip) Pragma: no-cache Host: requestb.in Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Length: 175 Connection: keep-alive Cache-Control: no-cache Accept-Encoding: gzip Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2  grant_type=refresh_token&refresh_token=******&client_id=*******.apps.googleusercontent.com&client_secret=****** 

Java code which sends the request:

RefreshTokenRequest req = new RefreshTokenRequest(new NetHttpTransport(), new JacksonFactory(), new GenericUrl(                     getSecrets().getDetails().getTokenUri()), REFRESH_TOKEN);             req.set("client_id", getSecrets().getDetails().getClientId());            req.set("client_secret", getSecrets().getDetails().getClientSecret());             TokenResponse response = req.execute(); 

Is there anything wrong?

like image 565
Martin V. Avatar asked Dec 14 '12 02:12

Martin V.


People also ask

How do I refresh my access token?

These client credentials and the refresh_token can be used to create a new value for the access_token . To refresh the access token, select the Refresh access token API call within the Authorization folder of the Postman collection. Next, click the Send button to request a new access_token .

What does unauthorized client mean?

unauthorized_client. The client is not authorized to request an authorization code using this method: The redirect_URI of the service either is incorrect or not provided.

How do I refresh an access token in Salesforce?

Request an Updated Access Token. A connected app can use the refresh token to get a new access token by sending one of the following refresh token POST requests to the Salesforce token endpoint. The connected app can send the client_id and client_secret in the body of the refresh token POST request, as shown here.

How do I get access token and refresh token oauth2?

Step 1 − First, the client authenticates with the authorization server by giving the authorization grant. Step 2 − Next, the authorization server authenticates the client, validates the authorization grant and issues the access token and refresh token to the client, if valid.


1 Answers

PROBLEM EXPLANATION

With the hint @MartinV gave I was finally able to fix it! Because his answer doesn't explain very well how to solve it, I'm going to post it here.

The problem is because we all have generated the Refresh Token using Google's OAuth Playground, but when you click 'Authorize APIs' in the first step, it takes you to the concent screen using the Playground app. After that, all the tokens that you create can be used only by the Playground app, but of course you don't know either the Client ID or the Client Secret for that app.

SOLUTION

The solution is to make Playground to use your own Client ID and Secret. To do so, click on the Settings button:

Playground settings

And enter your Client ID and Secret. But, before you do that, as it says there, you need to go to the Developer's Console, find your OAuth 2.0 client IDs client, edit it and add https://developers.google.com/oauthplayground under Authorized redirect URIs. After you added that and saved the changes, go back to the playground and try to Authorize APIs. In my case it took like 15 minutes before the changes in the Authorized redirect URIs took effect.

Once you're done, don't forget to remove the Playground URI from the Developer Console!

EXTRA

Once I have done that, in Python I did this and it worked:

access_token = None  client_id = 'xxxxxxxx.apps.googleusercontent.com' client_secret = 'xxxxxxxxxxxx' refresh_token = 'xxxxxxxxxxxx' token_expiry = None token_uri = "https://accounts.google.com/o/oauth2/token" user_agent = 'YourAgent/1.0'  credentials = client.GoogleCredentials(access_token, client_id, client_secret, refresh_token, token_expiry, token_uri, user_agent)  http = credentials.authorize(httplib2.Http()) credentials.refresh(http)  service = build('drive', 'v3', http=http) req = service.files().list() resp = req.execute(http=http) 
like image 80
Diego Jancic Avatar answered Sep 20 '22 16:09

Diego Jancic