Пример Oauth для Google API с использованием Python / Django
-
21-09-2019 - |
Вопрос
Я пытаюсь заставить Oauth работать с Google API, используя Python.Я пробовал различные библиотеки oauth, такие как oauth ( оавт ), oauth2 и djanog-oauth но я не могу заставить это работать (включая приведенные примеры).
Для отладки Oauth я использую Google Игровая площадка Oauth и я изучил API и тот Документация Oauth
С некоторыми библиотеками я борюсь с получением правильной подписи, с другими библиотеками я борюсь с преобразованием токена запроса в авторизованный токен.Что бы мне действительно помогло, если бы кто-нибудь мог показать мне рабочий пример для Google API с использованием одной из вышеупомянутых библиотек.
Редактировать:Мой первоначальный вопрос не привел ни к каким ответам, поэтому я добавил свой код.Есть две возможные причины, по которым этот код не работает:
1) Google не авторизует мой токен запроса, но не совсем уверен, как это определить
2) Подпись для токена доступа недействительна, но тогда я хотел бы знать, какие параметры oauth ожидает Google, поскольку я могу сгенерировать правильную подпись на первом этапе.
Это написано с использованием oauth2.py и для Django, отсюда и HttpResponseRedirect.
REQUEST_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetRequestToken'
AUTHORIZATION_URL = 'https://www.google.com/accounts/OAuthAuthorizeToken'
ACCESS_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetAccessToken'
CALLBACK = 'http://localhost:8000/mappr/mappr/oauth/' #will become real server when deployed
OAUTH_CONSUMER_KEY = 'anonymous'
OAUTH_CONSUMER_SECRET = 'anonymous'
signature_method = oauth.SignatureMethod_HMAC_SHA1()
consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY, secret=OAUTH_CONSUMER_SECRET)
client = oauth.Client(consumer)
request_token = oauth.Token('','') #hackish way to be able to access the token in different functions, I know this is bad, but I just want it to get working in the first place :)
def authorize(request):
if request.GET == {}:
tokens = OAuthGetRequestToken()
return HttpResponseRedirect(AUTHORIZATION_URL + '?' + tokens)
elif request.GET['oauth_verifier'] != '':
oauth_token = request.GET['oauth_token']
oauth_verifier = request.GET['oauth_verifier']
OAuthAuthorizeToken(oauth_token)
OAuthGetAccessToken(oauth_token, oauth_verifier)
#I need to add a Django return object but I am still debugging other phases.
def OAuthGetRequestToken():
print '*** OUTPUT OAuthGetRequestToken ***'
params = {
'oauth_consumer_key': OAUTH_CONSUMER_KEY,
'oauth_nonce': oauth.generate_nonce(),
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': int(time.time()), #The timestamp should be expressed in number of seconds after January 1, 1970 00:00:00 GMT.
'scope': 'https://www.google.com/analytics/feeds/',
'oauth_callback': CALLBACK,
'oauth_version': '1.0'
}
# Sign the request.
req = oauth.Request(method="GET", url=REQUEST_TOKEN_URL, parameters=params)
req.sign_request(signature_method, consumer, None)
tokens =client.request(req.to_url())[1]
params = ConvertURLParamstoDictionary(tokens)
request_token.key = params['oauth_token']
request_token.secret = params['oauth_token_secret']
return tokens
def OAuthAuthorizeToken(oauth_token):
print '*** OUTPUT OAuthAuthorizeToken ***'
params ={
'oauth_token' :oauth_token,
'hd': 'default'
}
req = oauth.Request(method="GET", url=AUTHORIZATION_URL, parameters=params)
req.sign_request(signature_method, consumer, request_token)
response =client.request(req.to_url())
print response #for debugging purposes
def OAuthGetAccessToken(oauth_token, oauth_verifier):
print '*** OUTPUT OAuthGetAccessToken ***'
params = {
'oauth_consumer_key': OAUTH_CONSUMER_KEY,
'oauth_token': oauth_token,
'oauth_verifier': oauth_verifier,
'oauth_token_secret': request_token.secret,
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': int(time.time()),
'oauth_nonce': oauth.generate_nonce(),
'oauth_version': '1.0',
}
req = oauth.Request(method="GET", url=ACCESS_TOKEN_URL, parameters=params)
req.sign_request(signature_method, consumer, request_token)
response =client.request(req.to_url())
print response
return req
def ConvertURLParamstoDictionary(tokens):
params = {}
tokens = tokens.split('&')
for token in tokens:
token = token.split('=')
params[token[0]] = token[1]
return params
Решение
У меня есть OAuth, работающий в приложении python App Engine:
http://github.com/sje397/Chess
Приложение запущено по адресу:
Другие советы
Эта работа для меня.
def login(request):
consumer_key = 'blabla'
consumer_secret = 'blabla'
callback = request.GET['callback']
request_token_url = 'https://api.linkedin.com/uas/oauth/requestToken'
authorize_url = 'https://api.linkedin.com/uas/oauth/authorize'
access_token_url = 'https://api.linkedin.com/uas/oauth/accessToken'
consumer = oauth.Consumer(consumer_key, consumer_secret)
if ('oauth_verifier' not in request.GET):
client = oauth.Client(consumer)
body = 'oauth_callback=http://shofin.com/login?callback='+callback+"&placeId="+request.GET[placeId]
resp,content = client.request(request_token_url,"POST",headers={'Content-Type':'application/x-www-form-urlencoded'},body=body)
request_token = dict(urlparse.parse_qsl(content))
loginUrl = authorize_url+"?oauth_token="+request_token['oauth_token']
cache.set(request_token['oauth_token'],request_token['oauth_token_secret'])
return HttpResponseRedirect(loginUrl)
elif request.GET['oauth_verifier']:
token = oauth.Token(request.GET['oauth_token'],cache.get(request.GET['oauth_token']))
token.set_verifier(request.GET['oauth_verifier'])
client = oauth.Client(consumer, token)
resp,content = client.request(access_token_url,"POST",{})
access_token = dict(urlparse.parse_qsl(content))
token = oauth.Token(key=access_token['oauth_token'], secret=access_token['oauth_token_secret'])
client = oauth.Client(consumer, token)
resp,json = client.request("http://api.linkedin.com/v1/people/~?format=json")
return render_to_response(callback,{'placeId':request.GET['placeId'],'userId':userId,'folkId':folkId)
Вы пробовали официальный gdata python api ?Он поставляется с клиентом oauth и скрывает сложность вызовов oauth.http://code.google.com/p/gdata-python-client/
Возможно, это и есть ответ.
При вызове OAuthGetRequestToken вы подписываете базовую строку своим consumer_secret, за которым следует & (амперсанд)
При вызове OAuthGetAccessToken вы подписываете базовую строку своим consumer_secret, за которым следует & (амперсанд), за которым следует token_secret .
Вы бы подписали базовую строку, используя (consumer_secret + "&") для OAuthGetRequestToken и вы бы подписали базовую строку, используя (consumer_secret + "&" + token_secret) для OAuthGetAccessToken
http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/ В методах PLAINTEXT и HMAC-SHA1 общий секрет представляет собой комбинацию секрета потребителя и секрета токена.
У Tornado есть рабочий код для Google oauth.Проверьте это здесь. авторизация в Google.Я использовал его и довольно хорошо работал "из коробки".Все, что вам нужно сделать, это извлечь класс и аккуратно поместить его в представление django.
PS:Tornado использует асинхронный модуль для возврата пользователя.Поскольку вы используете django, вам нужно полагаться на некоторую переменную get, чтобы определить, что пользователь только что предоставил доступ к вашему приложению.
IIRC Google oauth не совсем соответствует стандарту, вы иметь укажите, какую услугу вы запрашиваете (посмотрите на примеры, представленные в документах Google) в запросе в качестве дополнительного параметра, иначе это не сработает.