最近在用wxpyhon google 联系人应用, 不能避免的遇到了使用oauth 验证的问题。
首先贴一下关于 OAuth 2.0 的官方文档 https://developers.google.com/accounts/docs/OAuth2
然后再贴一下 中文文档 http://blog.csdn.net/totogogo/article/details/6860966
Google提供下列4种方式的OAuth 2.0:
该flow适用于那些Javascript-based web app,这种app因为以javascript为主,不需要maintain state over time (例如不需要用session来存储state)。
This flow is meant for web applications with servers that can keep secrets and maintain state.
This flow is meant for mobile, and desktop installed applications that wantaccess to user data.
该flow适用于那些想access google data的application which运行在device上,但无法进行用户授权(e.g. game consoles or media hubs), 需要使用另一个PC or device来进行用户授权的动作的case。
英文原文:This flow is suitable for applications executing on devices which wantaccess to user data, but don't have an easy data-entry method (e.g. game consoles or media hubs), and where the end-user has separate access to a user-agent on another computer or device (e.g. home computer, a latop, or asmart phone).
由于我使用的是wxpython 是第三种安装的应用程序,就只说一下这个的使用方法。
这里获取access token有两种方式,一种是使用 http 请求, 另一种是使用 gdata.gauth
http 请求比较灵活, 但是比较适合在线使用, 保存token 也比较麻烦, 首先说一下http 请求的使用方式
step1 发送用户信息 到 OAuth
#示例 def gen_url(url, data): ''' 生成url- ''' params = '&'.join([str(arg)+'='+str(val) for arg, val in data.items()]) url = url + '?' + params return url url = "https://accounts.google.com/o/oauth2/auth" datas = { 'client_id'='21302922996.apps.googleusercontent.com' 'redirect_uri'='urn:ietf:wg:oauth:2.0:oob' 'scope'='https://www.google.com/m8/feeds/' 'response_type'=code' } auth_url = gen_url(url, data) webbrowser.open(auth_url)
参数
client_id 创建的应用id (如果还没创建应用 请点击上边上文链接查看如何创建)
redirect_uri 获取token后的跳转链接地址 安装的应用程序为 urn:ietf:wg:oauth:2.0:oob web应用这里应该是http 地址
scope 你要认证的API 这里使用的google contacts API 其它API scope 请查看 https://developers.google.com/oauthplayground/
response_type 相应类型 这里是code web应用为 token
step2 当上边的请求发出后
会打开浏览器认证, 登录、授权、然后获取 authorization code
step3 获取authorization code 后 post 请求https://accounts.google.com/o/oauth2/token
参数包括
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp6
client_id=21302922996.apps.googleusercontent.com
client_secret=XTHhXh1SlUNgvyWGwDk1EjXB
redirect_uri=https://www.example.com/back
grant_type=authorization_code
认证成功后会得到一个JSON object 内容如下
{ "access_token":"1/fFAGRNJru1FTz70BzhT3Zg", "expires_in":3600, "token_type":"Bearer", "refresh_token":"1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ" }
然后就可以用access_token 作为参数访问api了
以上是http 方式获取token的方式
现在我们介绍第二种 使用gdata.gauth 获取
使用代码的方式讲解吧,比较清晰一些
#!/usr/bin/python # * coding: utf8 * ''' File: contact_login.py Author: goodspeed Date: 20130505 17:00:36 CST Description: google contacts login model ''' from __future__ import unicode_literals import wx import webbrowser import gdata.gauth import atom.http_core APP_NAME = 'YOUR App name' CLIENT_ID = 'YOUR CLIENT_ID' CLIENT_SECRET = 'YOUR CLIENT_SECRET' SCOPE = 'https://www.google.com/m8/feeds/' REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob' OAUTH_URL = 'https://accounts.google.com/o/oauth2/auth' TOKEN_URO = 'https://accounts.google.com/o/oauth2/token' USER_AGENT = 'dummysample' def get_auth_code(): ''' 获取authorization code ''' auth_token = gdata.gauth.OAuth2Token( client_id = CLIENT_ID, client_secret = CLIENT_SECRET, scope = SCOPE, user_agent='', ) redirect_uri = REDIRECT_URI auth_url = auth_token.generate_authorize_url(redirect_uri=redirect_uri) #在浏览器打开url 完成登录 授权步骤 获取authorization code webbrowser.open(auth_url) def get_access_token(auth_token, auth_code): ''' 用得到的 authorization code 获取access token 然后保存 ''' redirect_url = '%s?code=%s' % (REDIRECT_URI, auth_code) url = atom.http_core.ParseUri(redirect_url) token = auth_token.get_access_token(url.query) token = gdata.gauth.token_to_blob(auth_token) return auth_token #登录 入口 def singin(): #获取已保存token 弱没有token=None try: with open('token', 'r') as to: token = to.read() try: token = gdata.gauth.token_from_blob(token) except gdata.gauth.UnsupportedTokenType, e: raise e except: token = None #首先判断是否有已保存的token #如果有直接使用 没有重新获取 if token: auth_token = token else: auth_token = get_auth_code() auth_code = enter_auth_code() auth_token = get_access_token(auth_token, auth_code) return auth_token #将 authorization code 复制到dialog, 传回wxpyton def enter_auth_code(): dialog = wx.TextEntryDialog(None, 'enter authorization code!', 'enter authorization code', '', style=wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: #返回 authorization code return dialog.GetValue() dialog.Destroy()
if __name__ == '__main__':
singin()
现在就可以用auth_token来访问API了
#!/usr/bin/python # -*- coding: utf-8 -*- ''' File: contacts_operate.py Author: goodspeed Date: 2013-05-07 20:13:14 CST Description: contacts data operate ''' from __future__ import unicode_literals import gdata.contacts.client as gd from login_contact import APP_NAME def query_contacts(auth_token): gd_client = gd.ContactsClient(source=APP_NAME) gd_client = auth_token.authorize(gd_client) query = gd.ContactsQuery(max_results=200) feed = gd_client.GetContacts(q = query) for i, entry in enumerate(feed.entry): if entry.name: print i, entry.name.full_name.text
就是这些。。现在正在学习如果有不对的地方请提醒一下。谢谢