资讯专栏INFORMATION COLUMN

OAuth 2.0简单实战(以新浪开发平台为例)

ymyang / 3225人阅读

摘要:背景本人去年在打酱油的时候曾经要求抓过新浪微博的有关数据。然而要读写这些微博信息和朋友关系,必须要在新浪围脖平台上注册应用。

背景

本人去年在UCLA打酱油的时候曾经要求抓过新浪微博的有关数据。然而要读写这些微博信息和朋友关系,必须要在新浪围脖平台上注册应用。也就是要接触 OAuth 2.0 这个东西。当时基本不懂,今天看到了阮一峰博客上的这篇文章,决定自己动手一试。

准备

首先,你要把阮一峰博客上的这篇文章 粗略的读一遍。

然后你要上 新浪开发平台 注册一个应用,我注册的是微连接 - 网页应用

打开界面你可以看到App KeyApp Secret,这是要用的东西

好,接下来下载新浪微博python SDK,我们用Python进行分析

分析

首先,我们先根据微博API上面的HOW-TO 文档上来做

</>复制代码

  1. from weibo import APIClient
  2. APP_KEY = "1234567" # app key
  3. APP_SECRET = "abcdefghijklmn" # app secret
  4. CALLBACK_URL = "http://www.example.com/callback"
  5. client = APIClient(app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=CALLBACK_URL)
  6. url = client.get_authorize_url()

这样就拿到了URL了,你打开这个URL一看,正是提示你要授权应用(出现error:redirect_uri_mismatch 同学请到新浪微博开发界面填好redirect_uri)

好,我们看看源码

</>复制代码

  1. class APIClient(object):
  2. """
  3. API client using synchronized invocation.
  4. """
  5. def __init__(self, app_key, app_secret, redirect_uri=None, response_type="code", domain="api.weibo.com", version="2"):
  6. self.client_id = str(app_key)
  7. self.client_secret = str(app_secret)
  8. self.redirect_uri = redirect_uri
  9. self.response_type = response_type
  10. self.auth_url = "https://%s/oauth2/" % domain
  11. self.api_url = "https://%s/%s/" % (domain, version)
  12. self.access_token = None
  13. self.expires = 0.0
  14. self.get = HttpObject(self, _HTTP_GET)
  15. self.post = HttpObject(self, _HTTP_POST)
  16. self.upload = HttpObject(self, _HTTP_UPLOAD)
  17. def get_authorize_url(self, redirect_uri=None, **kw):
  18. """
  19. return the authorization url that the user should be redirected to.
  20. """
  21. redirect = redirect_uri if redirect_uri else self.redirect_uri
  22. if not redirect:
  23. raise APIError("21305", "Parameter absent: redirect_uri", "OAuth2 request")
  24. response_type = kw.pop("response_type", "code")
  25. return "%s%s?%s" % (self.auth_url, "authorize",
  26. _encode_params(client_id = self.client_id,
  27. response_type = response_type,
  28. redirect_uri = redirect, **kw))

client_id,redirect_url,app_key,好熟悉啊,仔细一看,原来是授权码模式的第一步

</>复制代码

  1. The client constructs the request URI by adding the following

  2. parameters to the query component of the authorization endpoint URI
  3. using the "application/x-www-form-urlencoded" format, per Appendix B:

  4. response_type

  5. REQUIRED. Value MUST be set to "code".

  6. client_id

  7. REQUIRED. The client identifier as described in Section 2.2.

  8. redirect_uri

  9. OPTIONAL. As described in Section 3.1.2.

  10. scope

  11. OPTIONAL. The scope of the access request as described by
  12. Section 3.3.

  13. state

  14. RECOMMENDED. An opaque value used by the client to maintain
  15. state between the request and callback. The authorization
  16. server includes this value when redirecting the user-agent back
  17. to the client. The parameter SHOULD be used for preventing
  18. cross-site request forgery as described in Section 10.12.

好了,当我们把账号密码填写好了之后验证成功后,你发现你的浏览器上面的URL发生了变化,到底是这么回事呢,请看第二步Authorization Response

</>复制代码

  1. If the resource owner grants the access request, the authorization

  2. server issues an authorization code and delivers it to the client by
  3. adding the following parameters to the query component of the
  4. redirection URI using the "application/x-www-form-urlencoded" format,
  5. per Appendix B:

  6. code

  7. REQUIRED. The authorization code generated by the
  8. authorization server. The authorization code MUST expire
  9. shortly after it is issued to mitigate the risk of leaks. A
  10. maximum authorization code lifetime of 10 minutes is
  11. RECOMMENDED. The client MUST NOT use the authorization code more than once. If an authorization code is used more than
  12. once, the authorization server MUST deny the request and SHOULD
  13. revoke (when possible) all tokens previously issued based on
  14. that authorization code. The authorization code is bound to
  15. the client identifier and redirection URI.

  16. state

  17. REQUIRED if the "state" parameter was present in the client
  18. authorization request. The exact value received from the
  19. client.

  20. For example, the authorization server redirects the user-agent by

  21. sending the following HTTP response:

</>复制代码

  1. HTTP/1.1 302 Found
  2. Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
  3. &state=xyz

然后我们继续按照API的指示做

</>复制代码

  1. # 获取URL参数code:
  2. code = your.web.framework.request.get("code")
  3. r = client.request_access_token(code)
  4. def request_access_token(self, code, redirect_uri=None):
  5. redirect = redirect_uri if redirect_uri else self.redirect_uri
  6. if not redirect:
  7. raise APIError("21305", "Parameter absent: redirect_uri", "OAuth2 request")
  8. r = _http_post("%s%s" % (self.auth_url, "access_token"),
  9. client_id = self.client_id,
  10. client_secret = self.client_secret,
  11. redirect_uri = redirect,
  12. code = code, grant_type = "authorization_code")
  13. return self._parse_access_token(r)

这个获得code 方法通常可以有很多,但是我们既然是实验,就手动复制code 吧。

哈哈,很明显request_access_token 这个方法就是发一个HTTP POST 包嘛

第三步Access Token Request

</>复制代码

  1. The client makes a request to the token endpoint by sending the

  2. following parameters using the "application/x-www-form-urlencoded"
  3. format per Appendix B with a character encoding of UTF-8 in the HTTP
  4. request entity-body:

  5. grant_type

  6. REQUIRED. Value MUST be set to "authorization_code".

  7. code

  8. REQUIRED. The authorization code received from the
  9. authorization server.

  10. redirect_uri

  11. REQUIRED, if the "redirect_uri" parameter was included in the
  12. authorization request as described in Section 4.1.1, and their
  13. values MUST be identical.

  14. client_id

  15. REQUIRED, if the client is not authenticating with the
  16. authorization server as described in Section 3.2.1.

  17. If the client type is confidential or the client was issued client

  18. credentials (or assigned other authentication requirements), the
  19. client MUST authenticate with the authorization server as described
  20. in Section 3.2.1.

  21. For example, the client makes the following HTTP request using TLS

  22. (with extra line breaks for display purposes only):

  23. </>复制代码

    1. POST /token HTTP/1.1
    2. Host: server.example.com
    3. Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
    4. Content-Type: application/x-www-form-urlencoded
    5. grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
    6. &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

最后一步

</>复制代码

  1. access_token = r.access_token # 新浪返回的token,类似abc123xyz456
  2. expires_in = r.expires_in # token过期的UNIX时间:http://zh.wikipedia.org/wiki/UNIX%E6%97%B6%E9%97%B4
  3. # TODO: 在此可保存access token
  4. client.set_access_token(access_token, expires_in)

就是从服务器返回的HTTP 包中解析access_tokenexpire_in 数据

同样来看RFC 文档中写的

</>复制代码

  1. If the access token request is valid and authorized, the

  2. authorization server issues an access token and optional refresh
  3. token as described in Section 5.1. If the request client
  4. authentication failed or is invalid, the authorization server returns
  5. an error response as described in Section 5.2.

  6. An example successful response:

  7. </>复制代码

    1. HTTP/1.1 200 OK
    2. Content-Type: application/json;charset=UTF-8
    3. Cache-Control: no-store
    4. Pragma: no-cache
    5. {
    6. "access_token":"2YotnFZFEjr1zCsicMWpAA",
    7. "token_type":"example",
    8. "expires_in":3600,
    9. "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
    10. "example_parameter":"example_value"
    11. }

接下来就可以调用API啦~

对于最后两步看的很累的话,可以自己尝试写一个

</>复制代码

  1. import urllib, urllib2
  2. APP_KEY = "2613134348"
  3. APP_SECRET = "5a14f41598a7444c7e0dc0422519b091" # app secret
  4. ACCESS_TOKEN = "9cd1b3869e62491331caf444456953e8"
  5. data = {
  6. "grant_type" : "authorization_code",
  7. "code" :ACCESS_TOKEN,
  8. "redirect_uri":"http://www.ceclinux.org",
  9. "client_id":APP_KEY,
  10. "client_secret":APP_SECRET
  11. }
  12. headers = {"host":"api.weibo.com","Authorization":"OAuth2 %s" % ACCESS_TOKEN}
  13. data = urllib.urlencode(data)
  14. request = urllib2.Request("https://api.weibo.com/oauth2/access_token", data, headers)
  15. response = urllib2.urlopen(request)
  16. print response.read()

运行这个文件
最后也能得到一个包含access_tokenexpire_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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37402.html

相关文章

  • OAuth 2.0协议在SAP产品中的应用

    摘要:阮一峰老师曾经在他的博文理解里对这个概念有了深入浅出的阐述。注这是阮一峰老师文章里提到的中的认证模式之一简化模式客户听起来不错这样我就不需要把我们公司的用户的密码提供给您了。这下您放心了吧注这种方式即阮一峰文章里介绍的授权码模式。 阮一峰老师曾经在他的博文理解OAuth 2.0里对这个概念有了深入浅出的阐述。 http://www.ruanyifeng.com/blo... 本文会结合...

    qiangdada 评论0 收藏0
  • OAuth 2.0协议在SAP产品中的应用

    摘要:阮一峰老师曾经在他的博文理解里对这个概念有了深入浅出的阐述。注这是阮一峰老师文章里提到的中的认证模式之一简化模式客户听起来不错这样我就不需要把我们公司的用户的密码提供给您了。这下您放心了吧注这种方式即阮一峰文章里介绍的授权码模式。 阮一峰老师曾经在他的博文理解OAuth 2.0里对这个概念有了深入浅出的阐述。 http://www.ruanyifeng.com/blo... 本文会结合...

    princekin 评论0 收藏0
  • 利用新浪API实现数据的抓取微博数据爬取微博爬虫

    摘要:本人长期出售超大量微博数据旅游网站评论数据,并提供各种指定数据爬取服务,。如果用户传入伪造的,则新浪微博会返回一个错误。 PS:(本人长期出售超大量微博数据、旅游网站评论数据,并提供各种指定数据爬取服务,Message to YuboonaZhang@Yahoo.com。由于微博接口更新后限制增大,这个代码已经不能用来爬数据了。如果只是为了收集数据可以咨询我的邮箱,如果是为了学习爬虫,...

    liuyix 评论0 收藏0

发表评论

0条评论

ymyang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<