2010-02-17 6 views
35

Sto cercando di ottenere Oauth che lavora con l'API di Google utilizzando Python. Ho provato diverse librerie oauth come oauth, oauth2 e djanog-oauth ma non riesco a farlo funzionare (inclusi gli esempi forniti).Esempio di Oauth per API Google con Python/Django

Per il debug Oauth uso di Google di Oauth Playground e ho studiato la API e la Oauth documentation

Con alcune librerie sto lottando con ottenere una firma a destra, con altre biblioteche sto lottando con la conversione del token di richiesta a un autorizzato gettone. Cosa mi sarebbe di grande aiuto se qualcuno potesse mostrarmi un esempio funzionante per l'API di Google utilizzando una delle librerie sopra citate.

EDIT: La mia domanda iniziale non ha portato a nessuna risposta, quindi ho aggiunto il mio codice. Ci sono due possibili cause per cui questo codice non funziona:
1) Google non autorizza il mio token di richiesta, ma non sono sicuro di come rilevare questo
2) La firma per il token di accesso non è valida, ma poi mi piacerebbe sapere quali sono i parametri di Google che mi aspetto in quanto sono in grado di generare una firma appropriata nella prima fase.

Questo è stato scritto usando oauth2.py e per Django quindi 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 

risposta

2

Questa potrebbe essere la risposta.

Quando si chiama OAuthGetRequestToken si firma il base_string con il consumer_secret seguito da un & (e commerciale)

Quando si chiama OAuthGetAccessToken si firma il base_string con il consumer_secret seguito da un & (e commerciale), seguita da token_secret.

Si potrebbe firmare il base_string utilizzando (consumer_secret + "& ") per OAuthGetRequestToken e si dovrebbe firmare il base_string utilizzando (consumer_secret +" &" + token_secret) per OAuthGetAccessToken

http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/ Nel PLAINTEXT e Metodi HMAC-SHA1, il segreto condiviso è la combinazione di Segreto consumatore e Segreto token.

+0

Grazie !!! Questo salva la mia giornata !!! – VHanded

0

IIRC Google OAuth non è del tutto seguendo lo standard, è necessario specificare quale servizio si sta richiedendo per (guardate gli esempi forniti nella documentazione di Google) nella richiesta come parametro aggiuntivo, oppure non funzionerà

2

Tornado ha un codice funzionante per Google oauth. Controllalo qui. google auth. L'ho usato e ho lavorato abbastanza bene fuori dagli schemi. Tutto ciò che devi fare è cogliere la classe e metterla attentamente in una visione django.

PS: Tornado utilizza il modulo asincrono per la restituzione dell'utente. Poiché stai usando django, devi fare affidamento su alcune variabili get per identificare che un utente ha appena concesso l'accesso alla tua applicazione.

+0

questo esempio utilizza solo il codice backend dell'API di Google+ oppure è un misto o sia il client che il back-end? –

4

questo lavoro per me.

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)