OAuth 2.0简单实战(以新浪开发平台为例)
2015-01-05 19:05
429 查看
背景
本人去年在UCLA打酱油的时候曾经要求抓过新浪微博的有关数据。然而要读写这些微博信息和朋友关系,必须要在新浪围脖平台上注册应用。也就是要接触OAuth 2.0这个东西。当时基本不懂,今天看到了阮一峰博客上的这篇文章,决定自己动手一试。
准备
首先,你要把阮一峰博客上的这篇文章 粗略的读一遍。然后你要上 新浪开发平台 注册一个应用,我注册的是微连接 - 网页应用
打开界面你可以看到App Key和App Secret,这是要用的东西
好,接下来下载新浪微博python SDK,我们用
Python进行分析
分析
首先,我们先根据微博API上面的HOW-TO 文档上来做from weibo import APIClient APP_KEY = '1234567' # app key APP_SECRET = 'abcdefghijklmn' # app secret CALLBACK_URL = 'http://www.example.com/callback' client = APIClient(app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=CALLBACK_URL) url = client.get_authorize_url()
这样就拿到了URL了,你打开这个URL一看,正是提示你要授权应用(出现
error:redirect_uri_mismatch同学请到新浪微博开发界面填好
redirect_uri)
好,我们看看源码
class APIClient(object): ''' API client using synchronized invocation. ''' def __init__(self, app_key, app_secret, redirect_uri=None, response_type='code', domain='api.weibo.com', version='2'): self.client_id = str(app_key) self.client_secret = str(app_secret) self.redirect_uri = redirect_uri self.response_type = response_type self.auth_url = 'https://%s/oauth2/' % domain self.api_url = 'https://%s/%s/' % (domain, version) self.access_token = None self.expires = 0.0 self.get = HttpObject(self, _HTTP_GET) self.post = HttpObject(self, _HTTP_POST) self.upload = HttpObject(self, _HTTP_UPLOAD) def get_authorize_url(self, redirect_uri=None, **kw): ''' return the authorization url that the user should be redirected to. ''' redirect = redirect_uri if redirect_uri else self.redirect_uri if not redirect: raise APIError('21305', 'Parameter absent: redirect_uri', 'OAuth2 request') response_type = kw.pop('response_type', 'code') return '%s%s?%s' % (self.auth_url, 'authorize', \ _encode_params(client_id = self.client_id, \ response_type = response_type, \ redirect_uri = redirect, **kw))
client_id,
redirect_url,
app_key,好熟悉啊,仔细一看,原来是授权码模式的第一步
The client constructs the request URI by adding the following
parameters to the query component of the authorization endpoint URI
using the "application/x-www-form-urlencoded" format, per Appendix B:
response_type
REQUIRED. Value MUST be set to "code".
client_id
REQUIRED. The client identifier as described in Section 2.2.
redirect_uri
OPTIONAL. As described in Section 3.1.2.
scope
OPTIONAL. The scope of the access request as described by
Section 3.3.
state
RECOMMENDED. An opaque value used by the client to maintain
state between the request and callback. The authorization
server includes this value when redirecting the user-agent back
to the client. The parameter SHOULD be used for preventing
cross-site request forgery as described in Section 10.12.
好了,当我们把账号密码填写好了之后验证成功后,你发现你的浏览器上面的URL发生了变化,到底是这么回事呢,请看第二步Authorization Response
If the resource owner grants the access request, the authorization
server issues an authorization code and delivers it to the client by
adding the following parameters to the query component of the
redirection URI using the "application/x-www-form-urlencoded" format,
per Appendix B:
code
REQUIRED. The authorization code generated by the
authorization server. The authorization code MUST expire
shortly after it is issued to mitigate the risk of leaks. A
maximum authorization code lifetime of 10 minutes is
RECOMMENDED. The client MUST NOT use the authorization code more than once. If an authorization code is used more than
once, the authorization server MUST deny the request and SHOULD
revoke (when possible) all tokens previously issued based on
that authorization code. The authorization code is bound to
the client identifier and redirection URI.
state
REQUIRED if the "state" parameter was present in the client
authorization request. The exact value received from the
client.
For example, the authorization server redirects the user-agent by
sending the following HTTP response:
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz
然后我们继续按照API的指示做
# 获取URL参数code: code = your.web.framework.request.get('code') r = client.request_access_token(code) def request_access_token(self, code, redirect_uri=None): redirect = redirect_uri if redirect_uri else self.redirect_uri if not redirect: raise APIError('21305', 'Parameter absent: redirect_uri', 'OAuth2 request') r = _http_post('%s%s' % (self.auth_url, 'access_token'), \ client_id = self.client_id, \ client_secret = self.client_secret, \ redirect_uri = redirect, \ code = code, grant_type = 'authorization_code') return self._parse_access_token(r)
这个获得
code方法通常可以有很多,但是我们既然是实验,就手动复制
code吧。
哈哈,很明显
request_access_token这个方法就是发一个
HTTP POST包嘛
第三步Access Token Request
The client makes a request to the token endpoint by sending the
following parameters using the "application/x-www-form-urlencoded"
format per Appendix B with a character encoding of UTF-8 in the HTTP
request entity-body:
grant_type
REQUIRED. Value MUST be set to "authorization_code".
code
REQUIRED. The authorization code received from the
authorization server.
redirect_uri
REQUIRED, if the "redirect_uri" parameter was included in the
authorization request as described in Section 4.1.1, and their
values MUST be identical.
client_id
REQUIRED, if the client is not authenticating with the
authorization server as described in Section 3.2.1.
If the client type is confidential or the client was issued client
credentials (or assigned other authentication requirements), the
client MUST authenticate with the authorization server as described
in Section 3.2.1.
For example, the client makes the following HTTP request using TLS
(with extra line breaks for display purposes only):
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
最后一步
access_token = r.access_token # 新浪返回的token,类似abc123xyz456 expires_in = r.expires_in # token过期的UNIX时间:http://zh. 4000 wikipedia.org/wiki/UNIX%E6%97%B6%E9%97%B4 # TODO: 在此可保存access token client.set_access_token(access_token, expires_in)
就是从服务器返回的
HTTP包中解析
access_token和
expire_in数据
同样来看
RFC文档中写的
If the access token request is valid and authorized, the
authorization server issues an access token and optional refresh
token as described in Section 5.1. If the request client
authentication failed or is invalid, the authorization server returns
an error response as described in Section 5.2.
An example successful response:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
接下来就可以调用API啦~
对于最后两步看的很累的话,可以自己尝试写一个
import urllib, urllib2 APP_KEY = '2613134348' APP_SECRET = '5a14f41598a7444c7e0dc0422519b091' # app secret ACCESS_TOKEN = '9cd1b3869e62491331caf444456953e8' data = { 'grant_type' : 'authorization_code', 'code' :ACCESS_TOKEN, 'redirect_uri':'http://www.ceclinux.org', 'client_id':APP_KEY, 'client_secret':APP_SECRET } headers = {'host':'api.weibo.com','Authorization':'OAuth2 %s' % ACCESS_TOKEN} data = urllib.urlencode(data) request = urllib2.Request('https://api.weibo.com/oauth2/access_token', data, headers) response = urllib2.urlopen(request) print response.read()
运行这个文件
最后也能得到一个包含
access_token和
expire_date的JSON文件
没了~
参考
http://github.liaoxuefeng.com/sinaweibopy/ https://github.com/michaelliao/sinaweibopy/wiki/OAuth2-HOWTO http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html相关文章推荐
- 开放平台OAuth 2.0授权开发实践
- 开放平台OAuth 2.0授权开发实践
- 【实战\Java SSM快速开发仿慕课网在线教育平台项目笔记】第1章 课程项目整体概述(整体介绍及Eclipse,Maven,新浪SAE软件平台介绍)
- Aooms_基于SpringCloud的微服务基础开发平台实战_003_配置文件与简单的web环境搭建
- 《.Net 2.0模式开发实战》笔记2
- 简单理解asp.net 2.0 三层开发
- [翻译]在asp.net 2.0中开发一个简单的评级控件
- [翻译]在asp.net 2.0中开发一个简单的评级控件
- 实战揭秘:开发.Net平台应用系统框架 作者:孙亚民 本文选自:赛迪网
- 实战揭秘:开发.Net平台应用系统框架
- ASP.NET 2.0服务器控件开发之简单属性
- JAVA中DWR开发项目简单聊天实战经验
- 《.NET 2.0模式开发实战》Foundations of Object-Oriented Programming Using .NET 2.0 Patterns
- 试用版获得手记(四)科诺平台测试版实战上篇业务组件开发
- Rich Ajax 平台,第 1 部分: 简介-基于 Eclipse 开发模式的 Web 2.0
- Linux下的C编程实战之开发平台搭建
- ASP.NET 2.0服务器控件开发之简单属性
- 实战揭秘:开发.Net平台应用系统框架
- Nokia开发平台2.0(包含S80 2.0、S60 2.0和S40 2.0)已知问题V2.1(翻译)
- ASP.NET 2.0服务器控件开发之简单属性