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

前端 未结 10 1833
失恋的感觉
失恋的感觉 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:21

    Wow.. 2 years old question and not a good answer.. No surprise given that Google documentation is crap regarding this.

    The correct way to do this is by extending the Storage class oauth2client.client.Storage

    An example implementation(using mongodb collection _google_credentials) would be something like:

    class Storage(oauth2client.client.Storage):
    
    def __init__(self, key):
        super(Storage, self).__init__()
        self._key = key
    
    def locked_get(self):
        if not self._key: return None
        data = _google_credentials.find_one({'_id': self._key})
        if not data: return None
        credentials = oauth2client.client.Credentials.new_from_json(json.dumps(data))
        credentials.set_store(self)
        return credentials
    
    def locked_put(self, credentials):
        data = json.loads(credentials.to_json())
        _google_credentials.update_one({'_id': self._key}, {'$set': data}, 
            upsert=True)
        credentials.set_store(self)
    
    def locked_delete(self):
        bucket.delete(self._key)
    

    Then when you initially get the credentials after step2_exchange, you need to store them using Storage().put:

    e.g:

    credentials = flow.step2_exchange(code)
    Storage(user_id).put(credentials)
    

    When you need the credentials again, just do:

    credentials = Storage(user_id).get()
    
    0 讨论(0)
  • 2020-11-29 05:25

    You can construct an OAuth2Credentials instance directly like this:

    import httplib2
    from oauth2client import GOOGLE_REVOKE_URI, GOOGLE_TOKEN_URI, client
    
    CLIENT_ID = '<client_id>'
    CLIENT_SECRET = '<client_secret>'
    REFRESH_TOKEN = '<refresh_token>'
    
    credentials = client.OAuth2Credentials(
        access_token=None,  # set access_token to None since we use a refresh token
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET,
        refresh_token=REFRESH_TOKEN,
        token_expiry=None,
        token_uri=GOOGLE_TOKEN_URI,
        user_agent=None,
        revoke_uri=GOOGLE_REVOKE_URI)
    
    credentials.refresh(httplib2.Http())  # refresh the access token (optional)
    print(credentials.to_json())
    http = credentials.authorize(httplib2.Http())  # apply the credentials
    
    0 讨论(0)
  • 2020-11-29 05:26

    You can also use the requests library as well:

    import google.auth.transport.requests
    import requests
    
    request = google.auth.transport.requests.Request()
    
    credentials.refresh(request)
    

    Here is my sample code on an active project:

    acct_creds = {
      'token': self.attachment.account.google_drive_access_token,
      'refresh_token': self.attachment.account.google_drive_refresh_token,
      'client_id': settings.GOOGLE_CLIENT_ID,
      'client_secret': settings.GOOGLE_CLIENT_SECRET,
      'token_uri': 'https://37947.ngrok.io/authenticate/google/callback/',
      'scopes': 'https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.install',
    }
    credentials = google.oauth2.credentials.Credentials(**acct_creds)
    if credentials.valid:
        print("Credentials valid")
    else:
        request = google.auth.transport.requests.Request()
        credentials.refresh(request)
    

    google.auth.transport.requests module

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

    I recommend this method.

    from oauth2client import client, GOOGLE_TOKEN_URI
    
    CLIENT_ID = "client_id"
    CLIENT_SECRET = "client_secret"
    REFRESH_TOKEN = "refresh_token"
    
    
    credentials = client.OAuth2Credentials(
        access_token = None, 
        client_id = CLIENT_ID, 
        client_secret = CLIENT_SECRET, 
        refresh_token = REFRESH_TOKEN, 
        token_expiry = None, 
        token_uri = GOOGLE_TOKEN_URI,
        token_ id = None, 
        revoke_uri= None)
    
    http = credentials.authorize(httplib2.Http())
    

    Even if the access token has expired, the credential is still authorize because of the refresh token.

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