8

Ich möchte data.photos.service.PhotosService verwenden, um Fotos aus Picasa zu pushen und zu ziehen. Ich habe eine Serviceschlüsseldatei XXXXXXXX-privatekey.p12 von der Google-Konsole erhalten und versuche nun, diesen Schlüssel mit Google zu authentifizieren.Verwenden von OAuth2 mit Dienstkonto auf gdata in Python

Die Dokumentation für OAuth2 mit appengine hat mich dazu gebracht, den folgenden, dass die Verwendung wäre der Einsatz zu glauben:

f = file(settings.SITE_ROOT + '/aurora/' + settings.PRIVATE_KEY, 'rb') 
key = f.read() 
f.close() 

credentials = SignedJwtAssertionCredentials(settings.SERVICE_ACCOUNT_NAME, key, scope = 'http://picasaweb.google.com/data https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile') 
http = httplib2.Http() 
http = credentials.authorize(http) 
service = build("oauth2", "v2", http=http) 
user_info = None 
try: 
    user_info = service.userinfo().get().execute() 
    # neither of these two methods work 
    #gd_client.SetOAuthInputParameters(signature_method = gdata.auth.OAuthSignatureMethod.RSA_SHA1, consumer_key = "asdfasdfasdf.apps.googleusercontent.com", rsa_key = key, two_legged_oauth = True, requestor_id = user_info.get('email')) 
    #gd_client.auth_token = gdata.gauth.TwoLeggedOAuthRsaToken(consumer_key = user_info.get('email'), rsa_private_key = key, requestor_id = user_info.get('email')) 
except errors.HttpError, e: 
    logging.error('An error occurred: %s', e) 

user_inf0 = {u'verified_email': True, u'id': u'1234', u'name': u'[email protected]', u'email': u'[email protected]'} 

Das Problem ist, dass entweder Methode 1 unter Verwendung von SetOAuthInputParameters gibt einen ungültigen Token oder Methode 2 kehrt eine 403 restricted.

Ich bin am Ende meines Wissens durch Berge von Code zu lesen, die alle regelmäßigen 3-beinigen oauth tun, wenn ich es wirklich und wirklich nicht so machen will. Irgendwelche Ideen/Artikel, die ich noch nicht gesehen habe?

Antwort

19

Verwenden Sie gdata.gauth.OAuth2TokenFromCredentials.

auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials) 
gd_client = auth2token.authorize(gd_client) 

OAuth2TokenFromCredentials soll Sie verwenden apiclient und gdata zugleich helfen. Unter dem Deckblatt verwendet es die Anmeldeinformationen, um sicherzustellen, dass es über die Authentifizierungsinformationen verfügt, die zum Ausführen von gData-Aufrufen erforderlich sind.

Hinweis, wenn Sie immer noch 403 erhalten, kann es etwas ganz anderes sein. Ich habe ein Dienstkonto verwendet, um auf die Daten eines Benutzers zuzugreifen, und erhielt 403, weil ich den Benutzer beim Aufruf von SignedJwtAssertionCredentials nicht ordnungsgemäß angegeben hatte.

UPDATE: Hier ist das Grundmuster I verwendet:

from oauth2client.client import SignedJwtAssertionCredentials 
credentials = SignedJwtAssertionCredentials(
    "[email protected]", 
    open("keyfile").read(), 
    scope=(
        "https://www.googleapis.com/auth/drive", 
        "https://spreadsheets.google.com/feeds", 
        "https://docs.google.com/feeds" 
    ), # For example. 
    sub="[email protected]" 
) 
http = httplib2.Http() 
http = credentials.authorize(http) # Not needed? See comment below. 
auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials) 
gd_client = gdata.photos.service.PhotosService() # For example. 
gd_client = auth2token.authorize(gd_client) 
+0

Wie haben Sie den Benutzer im Aufruf 'SignedJwtAssertionCredentials' angegeben? – Gautam

+1

Ich habe die Antwort aktualisiert. –

+0

Ich bekomme HTTP 400 damit, ich benutze die Tabellenkalkulation API – Gautam

0

Wenn Sie MFA verwenden auf Ihrem Google-Konto, müssen Sie die Zustimmung Bildschirm Authentifizierungsmethode verwenden. Mit Picassa API funktioniert es nicht wie es ist, da die Anfrage-API etwas anders ist.

import gdata.gauth 
import os 
import pickle 
import gdata.photos.service 

clientid='xxx' # https://console.developers.google.com/apis/credentials 
clientsecret='xxx' 
Scope='https://picasaweb.google.com/data/' 
User_agent='myself' 

def GetAuthToken(): 
    if os.path.exists(".token"): 
     with open(".token") as f: 
      token = pickle.load(f) 
    else: 
     token = gdata.gauth.OAuth2Token(client_id=clientid,client_secret=clientsecret,scope=Scope,user_agent=User_agent) 
     print token.generate_authorize_url(redirect_uri='urn:ietf:wg:oauth:2.0:oob') 
     code = raw_input('What is the verification code? ').strip() 
     token.get_access_token(code) 
     with open(".token", 'w') as f: 
      pickle.dump(token, f) 
    return token 


token = GetAuthToken() 

gd_client = gdata.photos.service.PhotosService() 
old_request = gd_client.request 


def request(operation, url, data=None, headers=None): 
    headers = headers or {} 
    headers['Authorization'] = 'Bearer ' + token.access_token 
    return old_request(operation, url, data=data, headers=headers) 


gd_client.request = request 
photos = gd_client.GetUserFeed(kind='photo', limit='10') 
for photo in photos.entry: 
    print 'Recently added photo title:', photo.title.text 
Verwandte Themen