作者: xiaoyu
微信公众号: Python 爬虫之路
知乎: www.zhihu.com/people/...
解读爬虫中 HTTP 的秘密(基础篇)
解读爬虫中 HTTP 的秘密(高阶篇)
Python 爬虫之模拟登录京东商城
前两篇分享了 HTTP 的基本概念和高级用法, 以及京东模拟登录的实战内容本篇博主将会继续与大家分享 HTTP 中的另一个有趣内容: OAUTH, 它也是在爬虫的模拟登录中可能会用到的, 下面给大家详细介绍一下
OAUTH 的定义
引自百度百科的定义:
OAUTH 协议为用户资源的授权提供了一个安全的开放而又简易的标准与以往的授权方式不同之处是 OAUTH 的授权不会使第三方触及到用户的帐号信息(如用户名与密码), 即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权, 因此 OAUTH 是安全的 oAuth 是 Open Authorization 的简写
目前, 最新的 OAUTH 协议使用 2.0 版本, 具体内容被记录在 RFC6749 标准中, 可参考链接: tools.ietf.org/html/r...
OAUTH 的应用
一个简单而不陌生的例子
我们平时访问某个网站或论坛, 如果进行一些个人操作, 网页一般会弹出让我们先登录的提示如果这时候我没有账号又不想注册的话, 该怎么办呢? 我们通常会点击一个第三方的小图标 (比如微信) 而完成登录有些网站甚至没有用户注册的功能, 完全依靠第三方网站登录获取用户信息
比如我们使用微博账号来登录 segmentfault 网站
网页会首先被重定向到微博的登录界面进行登录, 我们输入我们的账号和密码后, segementfault 网站会根据从微博账号获取的信息 (比如你的微博头像昵称好友列表等) 来创建一个用户当然, segmentfault 是不会知道你的微博密码的, 因为我们必须保证用户登录信息的安全性而不能将密码明文出去这一系列的安全性的授权操作都源于使用了 OAUTH 协议
其实在这一过程中, OAUTH 协议解决了传统第三方登录方法的一些弊端, 比如:
避免了传统方法中直接使用用户名称和密码进行第三方登录的行为, 而是通过 token 的形式使登录过程更安全可靠
避免了传统方法中修改密码会丧失所有第三方程序授权的尴尬
避免了因任意一个第三方程序被破解而泄露用户信息的缺点
也正是机遇这些, OAUTH 就应运而生了那么, 上述的第三方授权登录过程到底是怎么实现的呢? 这一过程怎么进行的呢? 我们带着这些问题继续往下看
OAUTH 实现的思路
通过上面应用的介绍, 我们不难发现这其中可大概分为三个对象, 分别是:
客户端(上面的 segmentfault)
第三方(上面的 weibo)
用户(我们自己)
清楚这个之后, 我们看看 OAUTH 授权的大概思路
使用 OAUTH 协议, 客户端不会与第三方登录网站直接联系, 而是先通过一个授权的中间层来建立联系 (有的网站将授权服务器和资源服务器分开使用, 有的一起使用) 在这个授权层下, 用户密码等安全信息不会泄露给客户端, 而是通过反馈一个临时的令牌 token 来代替用户信息完成授权 token 相当于一把钥匙, 并且区别于用户密码, token 令牌是经过加密算法生成的, 一般的很难破解
另外, 用户可以指定 token 令牌的权限范围和有效期, 以适度的开放资源
得到授权后, 客户端就会带着 token, 并根据用户规定的权限范围和有效期来规矩的获取资源信息
这只是一个大体的思路, 说白了就是通过一个授权层隔离了客户端与用户信息, 并在授权层基础上使用了一把安全的钥匙来代替用户完成授权
OAUTH 的运行流程
基于这个思路, RFC6749 标准规定了四种不同的授权流程供选择, 分别是:
授权码模式(authorization code)
简化模式(implicit)
密码模式(resource owner password credentials)
客户端模式(client credentials)
上面提到的微博使用
OAUTH2.0 授权码模式
完成授权其它客户端进行第三方登录之前, 需要先在微博开放平台上注册一个应用, 在应用里填写自己的信息注册完后, 开放平台会给客户端 (比如上面提到的 segmentfault) 颁发一个 client_id 和一个 APP Secret, 供授权请求的使用
下面将详细介绍微博的授权流程, 即授权码模式, 其它模式可以参考官方文档: tools.ietf.org/html/r...
OAUTH 的详细实现过程
下面是 OAUTH2.0 协议的详细流程图:
博主以上面 segmentfault 通过微博第三方登录为例来详细说明 OAUTH 授权流程
<1> 第一步
首先用户点击微博图标进行第三方登录, 然后页面跳转到微博登录界面等待用户输入账号密码授权
登录界面 url 如下:
https://api.weibo.com/oauth2/authorize?client_id=1742025894&redirect_uri=https://segmentfault.com/user/oauth/weibo&scope=follow_app_official_microblog
客服端通过
application/x-www-form-urlencoded
格式并使用 UTF8 编码 将下列参数加入到 query string 中来建立 URI 请求
client_id: 即 segmentfault 在微博开放平台申请的应用 ID 号(需要)
redirect_uri: 用户授权后需要跳转到的 url 地址(可选)
scope: 用户授权的权限范围和有效期(可选)
<2> 第二步
页面跳转到上一步骤的 redirect_uri 地址并在末尾添加一个授权码 code 值, 在后面步骤中会用 code 值来换取 token
跳转地址如下:
https://segmentfault.com/user/oauth/weibo?code=e7ec7daeb7bbf8cb9d622152cd449ae0
参数说明:
code: 授权码, 且只能被客户端使用一次, 否则会被授权服务器拒绝该码与上面的应用 ID 和重定向 URI, 是一种映射关系
这也验证了 reponse_type 是 code 类型的正确性
<3> 第三步
segmentfault 客户端使用授权的 code 来获得钥匙 token
获取 token 可以通过对微博 OAuth2 的 access_token 接口进行 POST 请求完成, 请求链接: api.weibo.com/oauth2/...
当然, 请求还需要携带以下参数才行
client_id: 申请应用时分配的 AppKey
client_sceret: 申请应用时分配的 AppSecret
grant_type: 请求的类型, 填写 authorization_code
code: 调用 authorize 获得的 code 值
redirect_uri: 回调地址, 需需与注册应用里的回调地址一致
<4> 第四步
返回上步请求获得的 token 信息一个实例结果如下:
- {
- "access_token": "ACCESS_TOKEN",
- "expires_in": 1234,
- "remind_in":"798114",
- "uid":"12341234"
- }
参数说明:
access_token: 用户授权的唯一票据, 用于调用微博的开放接口, 同时也是第三方应用验证微博用户登录的唯一票据, 第三方应用应该用该票据和自己应用内的用户建立唯一影射关系, 来识别登录状态, 不能使用本返回值里的 UID 字段来做登录识别
expires_in:access_token 的生命周期, 单位是秒数
remind_in:access_token 的生命周期
uid: 授权用户的 UID, 本字段只是为了方便开发者, 减少一次 user/show 接口调用而返回的, 第三方应用不能用此字段作为用户登录状态的识别, 只有 access_token 才是用户授权的唯一票据
<5> 第五步
使用上一步获得的 token 获取用户的名称头像等信息可以通过请求如下链接:
api.weibo.com/2/users...
同时请求需要携带以上获取的 token 和 uid 参数
<6> 第六步
返回获取的用户名称头像等已授权信息
以上就是整个微博 OAUTH 授权流程的详细介绍
OAUTH 总结
本篇介绍了 OAUTH 的基本概念, 并以微博第三方登录授权为例详细了 OAUTH 的授权码工作流程
博主会在后续跟进一个爬虫模拟登录微博的实例来深入理解 OAUTH 流程, 敬请期待!
参考链接:
- open.weibo.com/wiki/OA...
- tools.ietf.org/html/r...
- www.ruanyifeng.com/blo...
来源: https://juejin.im/entry/5aa4a10a518825557918464d