Google API: getting Credentials from refresh token with oauth2client.client

前端 未结 10 1832
失恋的感觉
失恋的感觉 2020-11-29 05:06

I am using googles official oauth2client.client to access the google plus api. I have a refresh token (that does not expire) stored in a database, and need to recreate the

相关标签:
10条回答
  • 2020-11-29 05:07

    I solved this quite easily (you certainly miss this documentation). This is a snippet of my code that tries to use Picasa API to get all of album from active user:

        http = httplib2.Http(ca_certs=os.environ['REQUESTS_CA_BUNDLE'])
        try:
            http = self.oauth.credentials.authorize(http)
            response, album_list = http.request(Picasa.PHOTOS_URL, 'GET')
            if response['status'] == '403':
                self.oauth.credentials.refresh(http)
                response, album_list = http.request(Picasa.PHOTOS_URL, 'GET')
            album_list = json.load(StringIO(album_list))
        except Exception as ex:
            Logger.debug('Picasa: error %s' % ex)
            return {}
    

    Use the refresh method coming from oauth2client.client.OAuth2Credentials. I think it's even okay to use if response['status'] != '200'. Got to check that!

    0 讨论(0)
  • 2020-11-29 05:08

    You could store the entire credentials rather than only the refresh token:

    json = credentials.to_json()
    credentials = Credentials.new_from_json(json)
    

    Look at the Storage object which does it this way.

    0 讨论(0)
  • If you are using the 2018 Youtube Python Quickstart demo app using google-auth, you can't use oauth2client's storage.

    So here is the correct way of storing the credentials

    Here is a partially working solution for google-auth, missing the correct handling of the case where the token expires:

    import os
    import json
    import os.path
    import google.oauth2.credentials
    from google.oauth2.credentials import Credentials
    from googleapiclient.discovery import build
    from googleapiclient.errors import HttpError
    from google_auth_oauthlib.flow import InstalledAppFlow
    
    CLIENT_SECRETS_FILE = "client_secret.json"
    SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl']
    API_SERVICE_NAME = 'youtube'
    API_VERSION = 'v3'
    
    def get_authenticated_service():
    
      if os.path.isfile("credentials.json"):
        with open("credentials.json", 'r') as f:
          creds_data = json.load(f)
        creds = Credentials(creds_data['token'])
    
      else:
        flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
        creds = flow.run_console()
        creds_data = {
              'token': creds.token,
              'refresh_token': creds.refresh_token,
              'token_uri': creds.token_uri,
              'client_id': creds.client_id,
              'client_secret': creds.client_secret,
              'scopes': creds.scopes
          }
        print(creds_data)
        with open("credentials.json", 'w') as outfile:
          json.dump(creds_data, outfile)
      return build(API_SERVICE_NAME, API_VERSION, credentials = creds)
    
    def channels_list_by_username(service, **kwargs):
      results = service.channels().list(**kwargs).execute()
      print('This channel\'s ID is %s. Its title is %s, and it has %s views.' %
           (results['items'][0]['id'],
            results['items'][0]['snippet']['title'],
            results['items'][0]['statistics']['viewCount']))
    
    if __name__ == '__main__':
      os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
      service = get_authenticated_service()
      channels_list_by_username(service, part='snippet,contentDetails,statistics', forUsername='GoogleDevelopers')
    
    0 讨论(0)
  • 2020-11-29 05:17

    I use: oauth2client.client.GoogleCredentials

        cred = oauth2client.client.GoogleCredentials(access_token,client_id,client_secret,
                                              refresh_token,expires_at,"https://accounts.google.com/o/oauth2/token",some_user_agent)
        http = cred.authorize(httplib2.Http())
        cred.refresh(http)
        self.gmail_service = discovery.build('gmail', 'v1', credentials=cred)
    
    0 讨论(0)
  • 2020-11-29 05:19

    If you already have a Credentials object then you can refresh it like so:

    if refresh:
        import google_auth_httplib2
        # credentials instanceof google.oauth2.credentials.Credentials
        credentials.refresh(google_auth_httplib2.Request(httplib2.Http()))
    

    I had created the Credentials object from an old token JSON file like so:

        credentials = google.oauth2.credentials.Credentials(
            token=token_json['access_token'],
            refresh_token=token_json['refresh_token'],
            id_token=token_json['id_token'],
            token_uri=token_json['token_uri'],
            client_id=token_json['client_id'],
            client_secret=token_json['client_secret'],
            scopes=token_json['scopes'])
    

    In this way I was able to adapt some old oauth2client code.

    0 讨论(0)
  • 2020-11-29 05:20

    In case anyone is looking for the answer for how use a refresh token with google_auth_oauthlib, the following works for me:

    flow.oauth2session.refresh_token(flow.client_config['token_uri'],
                                     refresh_token=refresh_token,
                                     client_id=<MY_CLIENT_ID>,
                                     client_secret=flow.client_config['client_secret'])
    creds = google_auth_oauthlib.helpers.credentials_from_session(
        flow.oauth2session, flow.client_config)
    

    I cannot find anywhere where this is documented though.

    0 讨论(0)
提交回复
热议问题