Использование OAuth2 с учетной записью сервиса на gdata в python
Я хочу использовать data.photos.service.PhotosService
выдвигать и извлекать фотографии из Picasa. Я получил файл служебного ключа XXXXXXXX-privatekey.p12 из консоли Google и сейчас пытаюсь пройти проверку подлинности, используя указанный ключ в Google.
Документация для OAUTH2 с использованием appengine заставила меня поверить, что использование следующего было бы полезно:
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'asdfasdfasdf@developer.gserviceaccount.com', u'email': u'asdfasdfasdf@developer.gserviceaccount.com'}
Проблема в том, что любой метод 1, использующий SetOAuthInputParameters
возвращает неверный токен, или метод 2 возвращает 403 restricted
,
Я нахожусь в конце своего ума, читая горы кода, которые все делают обычную трехстороннюю речь, когда я действительно и действительно не хочу делать это таким образом. Какие идеи / статьи я еще не видел?
2 ответа
Используйте gdata.gauth.OAuth2TokenFromCredentials.
auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials)
gd_client = auth2token.authorize(gd_client)
OAuth2TokenFromCredentials разработан, чтобы помочь вам использовать apiclient и gdata одновременно. Под прикрытием он использует учетные данные, чтобы удостовериться, что у него есть информация об аутентификации, необходимая для выполнения вызовов gdata.
Обратите внимание, если вы все еще получаете 403, это может быть что-то совсем другое. Я использовал служебную учетную запись для доступа к данным пользователя и получал 403, потому что я не определил пользователя должным образом в вызове SignedJwtAssertionCredentials.
ОБНОВЛЕНИЕ: Вот основной шаблон, который я использовал:
from oauth2client.client import SignedJwtAssertionCredentials
credentials = SignedJwtAssertionCredentials(
"XXXXXXXXXXX@developer.gserviceaccount.com",
open("keyfile").read(),
scope=(
"https://www.googleapis.com/auth/drive",
"https://spreadsheets.google.com/feeds",
"https://docs.google.com/feeds"
), # For example.
sub="user@gmail.com"
)
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)
Если вы используете MFA в своей учетной записи Google, вам нужно использовать метод аутентификации экрана согласия. С API Picassa он не работает как есть, так как API запроса немного отличается.
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