16

Trying to get OAuth2 Google login working, this is the raw request that my app makes:

Method: POST

URL: https://www.googleapis.com/oauth2/v3/token

Headers: Content-Type: application/x-www-form-urlencoded

Values:

client_id: XXX-0123456789abcdef0123456789abcdef.apps.googleusercontent.com

client_secret: A1b2C3d4E5f6G7h8I9j0K1l2M

code: 1/A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0U1v

grant_type: authorization_code

redirect_uri: http://localhost:5000/callback/google/

And this is the response:

Status: 401 Unauthorized

Body:

{ "error": "invalid_client", "error_description": "Unauthorized" } 

Have verified that this is the exact request / response that my app is making (a Python app using Flask and rauth), and have verified that I can reproduce the exact same request / response using Postman.

Per instructions in other threads, I have done all of the following in the Google APIs console:

  • In "OAuth consent screen" settings, set "Product name" to something different than "Project name"
  • Also in "OAuth consent screen" settings, double-check that email is set
  • Enable the Google+ API
  • Enable the Gmail API
  • Recreate the client ID / secret
  • Double-check that there are no leading or trailing spaces in the client ID / secret values, I have copied them correctly from the API console

No matter what I do, still getting the same response of "invalid_client": "Unauthorized".

Help with this would be appreciated. Am trying to set up OAuth2-powered "Log in with X" functionality in my app, have gotten Facebook and Twitter working without issues, would like to get Google working too, but if I can't resolve this then I'm afraid I'll have to ditch Google auth.

0

2 Answers 2

13

Invalid client means that the client id or the client secret that you are using are not valid. They must be the ones you have downloaded from Google Developer console.

Tip: You might want to consider using the Google python client library it does all the heavy lifting for you.

from __future__ import print_function import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request # If modifying these scopes, delete the file token.pickle. SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'] def main(): """Shows basic usage of the Drive v3 API. Prints the names and ids of the first 10 files the user has access to. """ creds = None # The file token.pickle stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('drive', 'v3', credentials=creds) # Call the Drive v3 API results = service.files().list( pageSize=10, fields="nextPageToken, files(id, name)").execute() items = results.get('files', []) if not items: print('No files found.') else: print('Files:') for item in items: print(u'{0} ({1})'.format(item['name'], item['id'])) if __name__ == '__main__': main() 
Sign up to request clarification or add additional context in comments.

11 Comments

Thanks! I thought I had double-checked it thoroughly, but no... I had defined the client secret in an env variable correctly, but I was then passing in the wrong env variable when actually making the token request in my app. Also, the Google python client library uses https://www.googleapis.com/oauth2/v4/token (instead of v3), so I've changed my app to do the same, seems to work fine.
I had mistakenly added a space to my secret string, which was causing the issue
Spent a day after it, went this close to being full-scale mental. Finally printed out the query string and found out I forgot to pass the client_secret variable, so it was being evaluated to undefined ;-; I feel so dumb.
I refreshed my client secret file and still got the invalid_client/unauthorized error. I had to delete token.pickle. Once token.pickle was recreated with the new client secret the error disappeared.
@NayeemulIslamSwad i read your comment & checked whether I was doing the same, & yep I forgot to pass the secret id as well.
|
1

Refresh Cliente Secret File on https://console.cloud.google.com/apis/credentials and delete token pickle folder

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.