I am trying to get Oauth working with the Google API using Python. I have tried different oauth libraries such as oauth, oauth2 and djanog-oauth but I cannot get it to work (including the provided examples).
For debugging Oauth I use Google's Oauth Playground and I have studied the API and the Oauth documentation
With some libraries I am struggling with getting a right signature, with other libraries I am struggling with converting the request token to an authorized token. What would really help me if someone can show me a working example for the Google API using one of the above-mentioned libraries.
EDIT: My initial question did not lead to any answers so I have added my code. There are two possible causes of this code not working:
1) Google does not authorize my request token, but not quite sure how to detect this 2) THe signature for the access token is invalid but then I would like to know which oauth parameters Google is expecting as I am able to generate a proper signature in the first phase.This is written using开发者_开发知识库 oauth2.py and for Django hence the 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
I have OAuth working in a python App Engine app:
http://github.com/sje397/Chess
The app is running at:
http://your-move.appspot.com
This work for 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)
Have you tried the official gdata python api ? It ships with an oauth client and hides the complexity of oauth calls. http://code.google.com/p/gdata-python-client/
This may be the answer.
When calling OAuthGetRequestToken you sign the base_string with your consumer_secret followed by an & (ampersand)
When calling OAuthGetAccessToken you sign the base_string with your consumer_secret followed by an & (ampersand) followed by token_secret.
You would sign the base_string using (consumer_secret + "&") for OAuthGetRequestToken and you would sign the base_string using (consumer_secret + "&" + token_secret) for OAuthGetAccessToken
http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/ In the PLAINTEXT and HMAC-SHA1 methods, the shared secret is the combination of the Consumer Secret and Token Secret.
Tornado has working code for Google oauth. Check it out here. google auth. I 've used it and worked pretty well out of the box. All you need to do is pluck out the class and carefully put it into a django view.
PS: Tornado makes use of async module for the user to return. Since you are using django you need to rely on some get variable to identify that a user has just granted access to your application.
IIRC Google oauth is not quite following the standard, you have to specify what service you're requesting for (look at the examples provided in the google docs) in the request as an additional parameter, or it won't work.
精彩评论