2011-07-27 3 views
0

J'essaie de faire fonctionner OAuth dans un petit script Python. J'utilise python-oauth2 et j'essaie de me connecter à Google pour lister mes documents Google. Obtenir le jeton de requête et autoriser le jeton semble fonctionner correctement, mais chaque fois que j'essaie d'obtenir le jeton d'accès, j'obtiens une réponse HTTP 400 et le contenu de la réponse est "signature_invalid".Problème de Google OAuth: invalid_signature

Voici mon code:

import httplib2, os, sys, tempfile, urllib, urlparse 
import oauth2 as oauth 
#httplib2.debuglevel=1 

# this php script writes oauth_verifier to /tmp/verifier.txt 
oauth_callback = 'http://localhost/api.php' 

scope = 'https://docs.google.com/feeds/' 
xoauth_displayname = 'Adam\'s API Test' 
url = 'https://www.google.com/accounts/OAuthGetRequestToken?scope=%s&oauth_callback=%s&xoauth_displayname=%s' % (scope, oauth_callback, xoauth_displayname) 

######## OAUTH: GET REQUEST TOKEN ############# 
consumer = oauth.Consumer('anonymous','anonymous') 
client = oauth.Client(consumer) 
resp, content = client.request(url, 'GET') 
if resp['status'] == '200': 
    print 'OAuthGetRequestToken OK' 
else: 
    print 'OAuthGetRequestToken status: %s' % resp['status'] 
    print content 
    sys.exit(1) 

######## OAUTH: AUTHORIZE TOKEN ############### 
oauth_token = urlparse.parse_qs(content)['oauth_token'][0] 
url = 'https://www.google.com/accounts/OAuthAuthorizeToken?hd=default&oauth_token=%s' % urllib.quote_plus(oauth_token) 
print 'Visit this URL in your browser: %s' % url 
raw_input('Press ENTER once you have granted access...') 

######## OAUTH: GET ACCESS TOKEN ############## 
verifier = file('/tmp/verifier.txt').read().rstrip() 
url = 'https://www.google.com/accounts/OAuthGetAccessToken?oauth_token=%s&oauth_verifier=%s' % (oauth_token, verifier) 
resp, content = client.request(url, 'GET') 
if resp['status'] == '200': 
    print 'OAuthGetAccessToken OK' 
    print content 
else: 
    print 'OAuthGetAccessToken status: %s' % resp['status'] 
    print content 
    sys.exit(1) 

Toutes les idées?

Répondre

1

Avec l'aide d'Eva, je l'ai réparé! This post had the solution.

J'ai échoué à utiliser oauth_token_secret, renvoyé à partir de la demande d'origine pour un jeton non autorisé. J'ai raté que le Consumer était en train d'être réutilisé, mais un nouveau Client était instancié pour l'extraction de jetons d'accès à la fin du Twitter Three-legged OAuth Example in the python-oauth2 README.

Voici le patch pour corriger le code ci-dessus:

--- old.py 2011-07-28 10:38:06.904639958 -0500 
+++ new.py 2011-07-28 10:38:44.192639954 -0500 
@@ -22,6 +22,7 @@ 

######## OAUTH: AUTHORIZE TOKEN ############### 
oauth_token = urlparse.parse_qs(content)['oauth_token'][0] 
+oauth_token_secret = urlparse.parse_qs(content)['oauth_token_secret'][0] 
url = 'https://www.google.com/accounts/OAuthAuthorizeToken?hd=default&oauth_token=%s' % urllib.quote_plus(oauth_token) 
print 'Visit this URL in your browser: %s' % url 
raw_input('Press ENTER once you have granted access...') 
@@ -29,6 +30,7 @@ 
######## OAUTH: GET ACCESS TOKEN ############## 
verifier = file('/tmp/verifier.txt').read().rstrip() 
url = 'https://www.google.com/accounts/OAuthGetAccessToken?oauth_token=%s&oauth_verifier=%s' % (oauth_token, verifier) 
+client.token = oauth.Token(oauth_token, oauth_token_secret) 
resp, content = client.request(url, 'GET') 
if resp['status'] == '200': 
    print 'OAuthGetAccessToken OK' 

Et voici le code original, avec ce patch appliqué:

import httplib2, os, sys, tempfile, urllib, urlparse 
import oauth2 as oauth 
#httplib2.debuglevel=1 

# this php script writes oauth_verifier to /tmp/verifier.txt 
oauth_callback = 'http://localhost/api.php' 

scope = 'https://docs.google.com/feeds/' 
xoauth_displayname = 'Adam\'s API Test' 
url = 'https://www.google.com/accounts/OAuthGetRequestToken?scope=%s&oauth_callback=%s&xoauth_displayname=%s' % (scope, oauth_callback, xoauth_displayname) 

######## OAUTH: GET REQUEST TOKEN ############# 
consumer = oauth.Consumer('anonymous','anonymous') 
client = oauth.Client(consumer) 
resp, content = client.request(url, 'GET') 
if resp['status'] == '200': 
    print 'OAuthGetRequestToken OK' 
else: 
    print 'OAuthGetRequestToken status: %s' % resp['status'] 
    print content 
    sys.exit(1) 

######## OAUTH: AUTHORIZE TOKEN ############### 
oauth_token = urlparse.parse_qs(content)['oauth_token'][0] 
oauth_token_secret = urlparse.parse_qs(content)['oauth_token_secret'][0] 
url = 'https://www.google.com/accounts/OAuthAuthorizeToken?hd=default&oauth_token=%s' % urllib.quote_plus(oauth_token) 
print 'Visit this URL in your browser: %s' % url 
raw_input('Press ENTER once you have granted access...') 

######## OAUTH: GET ACCESS TOKEN ############## 
verifier = file('/tmp/verifier.txt').read().rstrip() 
url = 'https://www.google.com/accounts/OAuthGetAccessToken?oauth_token=%s&oauth_verifier=%s' % (oauth_token, verifier) 
client.token = oauth.Token(oauth_token, oauth_token_secret) 
resp, content = client.request(url, 'GET') 
if resp['status'] == '200': 
    print 'OAuthGetAccessToken OK' 
    print content 
else: 
    print 'OAuthGetAccessToken status: %s' % resp['status'] 
    print content 
    sys.exit(1) 

Notez que, en fait, oauth_token et oauth_verifier ne doivent pas nécessairement être ajouté manuellement à la chaîne de requête pour récupérer le jeton d'accès (python-oauth2 fait cela pour nous). J'ai laissé le code tel quel pour que je puisse illustrer le changement le plus simple du code non fonctionnel dans le message original au code de travail dans cette réponse. L'URL finale peut être simplement https://www.google.com/accounts/OAuthGetAccessToken.

Le contenu imprimé final crache oauth_token et oauth_token_secret. Ces paramètres sont utilisés dans les appels API suivants, tels que la récupération d'une liste de documents sur Google Documents.

est ici un exemple de code pour le faire:

import httplib2, os, sys, tempfile, urllib, urlparse 
import oauth2 as oauth 

######## OAUTH: GET REQUEST TOKEN ############# 
consumer = oauth.Consumer('anonymous', 'anonymous') 
creds = {'oauth_token_secret': 'INSERT_SECRET_FROM_ABOVE', 'oauth_token': 'INSERT_TOKEN_FROM_ABOVE'} 
client = oauth.Client(consumer) 
client.token = oauth.Token(creds['oauth_token'], creds['oauth_token_secret']) 
url = 'https://docs.google.com/feeds/default/private/full?v=3' 
resp, content = client.request(url, 'GET') 
if resp['status'] == '200': 
    print 'list status OK' 
    fh = open('/tmp/list.xml', 'w') 
    fh.write(content) 
    fh.close() 
else: 
    print 'list status: %s' % resp['status'] 
    print content 
    sys.exit(1)