2010-02-17 10 views
35

J'essaie de faire fonctionner Oauth avec l'API Google en utilisant Python. J'ai essayé différentes bibliothèques oauth telles que oauth, oauth2 et djanog-oauth mais je ne peux pas le faire fonctionner (y compris les exemples fournis).Oauth pour l'exemple de l'API Google en utilisant Python/Django

Pour le débogage OAuth J'utilise Google Oauth Playground et je l'ai étudié la API et la Oauth documentation

Avec certaines bibliothèques, je me bats à obtenir une bonne signature, avec d'autres bibliothèques, je me bats avec la conversion du jeton de demande à une personne autorisée jeton. Qu'est-ce qui pourrait vraiment m'aider si quelqu'un peut me montrer un exemple de travail pour l'API Google en utilisant l'une des bibliothèques mentionnées ci-dessus.

EDIT: Ma question initiale n'a pas donné de réponse, j'ai donc ajouté mon code. 1) Google n'autorise pas mon jeton de demande, mais je ne sais pas trop comment le détecter
2) La signature du jeton d'accès est invalide, mais je voudrais savoir Quels sont les paramètres attendus que Google attend car je suis en mesure de générer une signature correcte dans la première phase.

Ceci est écrit en utilisant oauth2.py et pour Django d'où le 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 

Répondre

2

Cela peut être la réponse.

Lorsque vous appelez OAuthGetRequestToken vous signez le base_string avec votre consumer_secret suivi d'un & (esperluette)

Lorsque vous appelez OAuthGetAccessToken vous signez le base_string avec votre consumer_secret suivi d'un & (esperluette) suivi par token_secret.

Vous signerez le base_string en utilisant (consumer_secret + "& ") pour OAuthGetRequestToken et vous signer le base_string en utilisant (consumer_secret +" &" + token_secret) pour OAuthGetAccessToken

http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/ Dans le texte en clair et Méthodes HMAC-SHA1, le secret partagé est la combinaison du secret client et du secret de jeton.

+0

Merci !!! Cela sauve ma journée !!! – VHanded

0

IIRC Google OAuth est pas tout à fait conformément à la norme, vous avez de préciser quel service que vous demandez pour (voir les exemples fournis dans les documents Google) dans la demande en tant que paramètre supplémentaire, ou ne fonctionnera pas.

2

Tornado a le code de travail pour Google oauth. Vérifiez le ici. google auth. Je l'ai utilisé et a très bien fonctionné hors de la boîte. Tout ce que vous avez à faire est d'arracher la classe et de la mettre soigneusement dans une vue django. PS: Tornado utilise le module asynchrone pour que l'utilisateur puisse revenir. Puisque vous utilisez django, vous devez utiliser une variable get pour identifier qu'un utilisateur vient d'accorder l'accès à votre application.

+0

cet exemple utilise uniquement le code backend de l'API Google+ ou est-ce un mélange ou un client et un backend? –

4

Ce travail pour moi.

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)