使用 Python / Django 的 Google API 示例的 Oauth

Posted

技术标签:

【中文标题】使用 Python / Django 的 Google API 示例的 Oauth【英文标题】:Oauth for Google API example using Python / Django 【发布时间】:2011-01-17 23:35:20 【问题描述】:

我正在尝试让 Oauth 使用 Python 与 Google API 一起工作。我尝试了不同的 oauth 库,例如 oauth、oauth2 和 djanog-oauth,但我无法让它工作(包括提供的示例)。

为了调试 Oauth,我使用 Google 的 Oauth Playground,我研究了 API 和 Oauth documentation

对于某些库,我正在努力获得正确的签名,而对于其他库,我正在努力将请求令牌转换为授权令牌。如果有人可以使用上述库之一向我展示 Google API 的工作示例,那将真正对我有什么帮助。

编辑:我最初的问题没有得到任何答案,所以我添加了我的代码。此代码无法正常工作有两个可能的原因: 1) Google 未授权我的请求令牌,但不太确定如何检测此 2) 访问令牌的签名无效,但我想知道 Google 期望哪些 oauth 参数,因为我能够在第一阶段生成正确的签名。

这是使用 oauth2.py 和 Django 编写的,因此是 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

【问题讨论】:

【参考方案1】:

这可能就是答案。

调用 OAuthGetRequestToken 时,您使用您的 consumer_secret 后跟一个 &(和号)对 base_string 进行签名

调用 OAuthGetAccessToken 时,您使用您的 consumer_secret 后跟一个 &(与号)和 token_secret 对 base_string 进行签名。

您将使用 (consumer_secret + "&") 为 OAuthGetRequestToken 和 您将使用 (consumer_secret + "&" + token_secret) 为 OAuthGetAccessToken 签署 base_string

http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/ 在 PLAINTEXT 和 HMAC-SHA1 方法中,共享密钥是 Consumer Secret 和 Token Secret 的组合。

【讨论】:

【参考方案2】:

你试过官方的gdata python api吗? 它附带一个 oauth 客户端并隐藏了 oauth 调用的复杂性。 http://code.google.com/p/gdata-python-client/

【讨论】:

【参考方案3】:

IIRC Google oauth 并未完全遵循标准,您必须在请求中指定您请求的服务(查看 google 文档中提供的示例)作为附加参数,否则将无法正常工作。

【讨论】:

【参考方案4】:

Tornado 具有适用于 Google oauth 的工作代码。在这里查看。 google auth。我已经使用它并且开箱即用地工作得很好。您需要做的就是挑选出类并小心地将其放入 django 视图中。

PS:Tornado 使用异步模块让用户返回。由于您使用的是 django,因此您需要依赖一些 get 变量来识别用户刚刚授予对您的应用程序的访问权限。

【讨论】:

此示例仅使用 Google+ API 后端代码还是混合使用或同时使用客户端和后端?【参考方案5】:

我在 Python App Engine 应用中使用 OAuth:

http://github.com/sje397/Chess

应用程序正在运行:

http://your-move.appspot.com

【讨论】:

【参考方案6】:

这对我有用。

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)

【讨论】:

以上是关于使用 Python / Django 的 Google API 示例的 Oauth的主要内容,如果未能解决你的问题,请参考以下文章

谷歌钱包应用内付款:未捕获的 ReferenceError:未定义 goog。 google.payments 与 goog.payments

如何将 goog.payments.inapp.buy 与 luciferous jwt 一起使用?

翻译:《实用的Python编程》02_04_Sequences

Googleplay为什么登不上,显示与Goog服务器通信时出现问题

使用 python3.6 安装 TensorFlow 失败

scss btn大小的goog例子,状态定义