Пример Oauth для Google API с использованием Python / Django - PullRequest
35 голосов
/ 17 февраля 2010

Я пытаюсь заставить Oauth работать с API Google, используя Python. Я пробовал разные библиотеки oauth, такие как oauth , oauth2 и djanog-oauth , но не могу заставить его работать (включая предоставленные примеры).

Для отладки Oauth я использую игровую площадку Google Oauth и изучил API и документацию Oauth

С некоторыми библиотеками я борюсь с получением правильной подписи, с другими библиотеками я пытаюсь преобразовать токен запроса в авторизованный токен. Что действительно помогло бы мне, если бы кто-нибудь мог показать мне рабочий пример API Google, используя одну из вышеупомянутых библиотек.

РЕДАКТИРОВАТЬ: Мой первоначальный вопрос не привел ни к каким ответам, поэтому я добавил свой код. Этот код не работает по двум причинам:
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

Ответы [ 6 ]

6 голосов
/ 20 июля 2010

OAuth работает в приложении Python App Engine:

http://github.com/sje397/Chess

Приложение работает по адресу:

http://your -move.appspot.com

4 голосов
/ 13 февраля 2012

Эта работа для меня.

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)
3 голосов
/ 28 июня 2010

Вы пробовали официальный API gdata Python?Он поставляется с клиентом oauth и скрывает сложность вызовов oauth.http://code.google.com/p/gdata-python-client/

2 голосов
/ 17 июля 2010

У Торнадо есть рабочий код для Google oauth. Проверьте это здесь. Google Auth . Я использовал это и работал довольно хорошо из коробки. Все, что вам нужно сделать, это вытащить класс и аккуратно поместить его в представление Django.

PS: Tornado использует асинхронный модуль для возврата пользователем. Поскольку вы используете django, вам нужно полагаться на переменную get, чтобы определить, что пользователь только что предоставил доступ к вашему приложению.

2 голосов
/ 15 июня 2010

Это может быть ответом.

При вызове OAuthGetRequestToken вы подписываете base_string с потребителем_secret, за которым следует символ & (амперсанд)

При вызове OAuthGetAccessToken вы подписываете base_string с вашим потребителем_secret, за которым следует & (амперсанд) с последующим token_secret.

Вы бы подписали base_string, используя (consumer_secret + "&") для OAuthGetRequestToken, и вы бы подписали base_string, используя (consumer_secret + "&" + token_secret) для OAuthGetAccessToken

http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/ В методах PLAINTEXT и HMAC-SHA1 общим секретом является сочетание секрета потребителя и секрета токена.

0 голосов
/ 08 июля 2010

IIRC Google oauth не совсем соответствует стандарту, у вас есть , чтобы указать, какую службу вы запрашиваете (посмотрите примеры, приведенные в документации Google) в запросе в качестве дополнительного параметра, или это не сработает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...