2010-02-17 16 views
35

Estoy tratando de hacer que Oauth trabaje con la API de Google usando Python. He intentado con diferentes bibliotecas de Oauth como oauth, oauth2 y djanog-oauth, pero no consigo que funcione (incluidos los ejemplos proporcionados).Ejemplo de Oauth for Google API usando Python/Django

Para depurar Oauth Yo uso Google de Oauth Playground y he estudiado la API y la Oauth documentation

Con algunas bibliotecas estoy luchando con conseguir una firma derecha, con otras bibliotecas estoy luchando con la conversión de la señal de petición a un autorizadas simbólico. Lo que realmente me ayudaría si alguien puede mostrarme un ejemplo de trabajo para la API de Google utilizando una de las bibliotecas mencionadas anteriormente.

EDIT: Mi pregunta inicial no dio ninguna respuesta, así que agregué mi código. Hay dos causas posibles de que este código no funcione:
1) Google no autoriza mi token de solicitud, pero no estoy muy seguro de cómo detectarlo
2) La firma del token de acceso no es válida pero me gustaría saber qué parámetros adicionales espera Google, ya que puedo generar una firma adecuada en la primera fase.

Esto está escrito usando oauth2.py y para Django de ahí el 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 

Respuesta

2

Esta puede ser la respuesta.

Al llamar OAuthGetRequestToken de firmar el base_string con su consumer_secret seguido de un & (comercial)

Al llamar OAuthGetAccessToken de firmar el base_string con su consumer_secret seguido de un & (ampersand) seguido de token_secret.

Se podría firmar el base_string usando (consumer_secret + "& ") para OAuthGetRequestToken y que firmaría el base_string usando (consumer_secret +" &" + token_secret) para OAuthGetAccessToken

http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/ En el texto en claro y Los métodos HMAC-SHA1, el secreto compartido es la combinación del secreto del consumidor y el secreto del token.

+0

Thanks !!! Esto ahorra mi día! – VHanded

0

IIRC Google OAuth no es del todo siguiendo el estándar, que tiene para especificar qué tipo de servicio que está solicitando (mirar los ejemplos proporcionados en los documentos de Google) en la solicitud como un parámetro adicional, o no funcionará

2

Tornado tiene código de trabajo para Google oauth. Compruébalo aquí. google auth. Lo he usado y funcionó bastante bien de la caja. Todo lo que necesitas hacer es sacar la clase y ponerla cuidadosamente en una vista django.

PD: Tornado hace uso del módulo asíncrono para que el usuario regrese. Como está utilizando django, necesita confiar en alguna variable get para identificar que un usuario acaba de otorgar acceso a su aplicación.

+0

este ejemplo usa solo el código de backend API de Google+ o es una mezcla de ambos, cliente y servidor? –

4

Este trabajo para mí.

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) 
Cuestiones relacionadas