it-swarm.com.de

Google API: Anmeldeinformationen vom Aktualisierungstoken mit oauth2client.client abrufen

Ich verwende den offiziellen oauth2client.client von Google, um auf Google Plus API zuzugreifen. Ich habe ein Aktualisierungstoken (das nicht abgelaufen ist) in einer Datenbank gespeichert, und ich brauche , Um die temporären "Berechtigungsnachweise" (Zugriffstoken) daraus neu zu erstellen.

Aber ich konnte keinen Weg finden, um dies mit der offiziellen Google-Bibliothek zu tun.

Also habe ich es gehackt: Ich habe mit urllib auf die API zugegriffen, die mir ein neues Access_token aus dem refresh_token gibt. Mit dem access_token kann ich dann die Bibliothek verwenden.

Ich muss etwas vermissen!

from apiclient import discovery
from oauth2client.client import AccessTokenCredentials
from urllib import urlencode
from urllib2 import Request , urlopen, HTTPError
import json

# ==========================================

def access_token_from_refresh_token(client_id, client_secret, refresh_token):
  request = Request('https://accounts.google.com/o/oauth2/token',
    data=urlencode({
      'grant_type':    'refresh_token',
      'client_id':     client_id,
      'client_secret': client_secret,
      'refresh_token': refresh_token
    }),
    headers={
      'Content-Type': 'application/x-www-form-urlencoded',
      'Accept': 'application/json'
    }
  )
  response = json.load(urlopen(request))
  return response['access_token']

# ==========================================

access_token = access_token_from_refresh_token(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN)

# now I can use the library properly
credentials = AccessTokenCredentials(access_token, "MyAgent/1.0", None)
http = credentials.authorize(httplib2.Http())
service = discovery.build('plus', 'v1', http=http)
google_request = service.people().get(userId='me')
result = google_request.execute(http=http)
15
bjelli

Ich verwende: 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)
17
leah

Ich habe das ziemlich leicht gelöst (Sie vermissen sicherlich diese Dokumentation ). Dies ist ein Auszug aus meinem Code, der versucht, die Picasa-API zu verwenden, um das gesamte Album vom aktiven Benutzer abzurufen:

    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 {}

Verwenden Sie die refresh-Methode aus oauth2client.client.OAuth2Credentials . Ich denke, es ist sogar okay, if response['status'] != '200' zu verwenden. Muss das überprüfen!

5
swdev

Sie können eine OAuth2Credentials -Instanz direkt wie folgt erstellen:

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
3
Eugene Yarmash

Ich empfehle diese Methode.

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())

Selbst wenn das Zugriffstoken abgelaufen ist, ist der Berechtigungsnachweis aufgrund des Aktualisierungstokens weiterhin autorisiert.

2
KiHyun Nam

Sie können die gesamten Anmeldeinformationen speichern und nicht nur das Aktualisierungstoken:

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

Schauen Sie sich das Storage-Objekt an das es so macht.

1
tjsar

Wenn Sie die 2018 Youtube Python Quickstart-Demo-App mit google-auth verwenden, können Sie den Speicher von oauth2client nicht verwenden.

Also hier ist der richtige Weg zum Speichern der Anmeldeinformationen

Hier ist eine teilweise funktionierende Lösung für google-auth, bei der die korrekte Behandlung des Falls, bei dem das Token abläuft, fehlt:

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 __== '__main__':
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
  service = get_authenticated_service()
  channels_list_by_username(service, part='snippet,contentDetails,statistics', forUsername='GoogleDevelopers')
1
Ray Hulha

Falls jemand nach der Antwort für die Verwendung eines Aktualisierungstokens mit google_auth_oauthlib Sucht, funktioniert für mich Folgendes:

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)

Ich kann jedoch nirgendwo etwas finden, wo dies dokumentiert ist.

0
Neil

Wow .. 2 Jahre alte Frage und keine gute Antwort .. Kein Wunder, dass die Dokumentation von Google diesbezüglich Mist ist.

Der richtige Weg, dies zu tun, ist die Erweiterung der Storage-Klasse oauth2client.client.Storage.

Eine Beispielimplementierung (mit mongodb collection _google_credentials) würde etwa so aussehen:

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)

Wenn Sie die Berechtigungsnachweise zunächst nach step2_exchange abrufen, müssen Sie sie mit Storage().put speichern:

z.B:

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

Wenn Sie die Anmeldeinformationen erneut benötigen, führen Sie einfach Folgendes aus:

credentials = Storage(user_id).get()
0
599644