Oauth2原理、使用
原理
快递员–>门禁–>小区–>我家 <=====> 第三方应用 --> 微信墙 —>账号–>个人数据
简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
OAuth 的核心就是向第三方应用颁发令牌
令牌特点:
(1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
(2)令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。
(3)令牌有权限范围(scope),比如只能进小区的二号门。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。
OAuth是什么?
引入了一个授权层,用来分离两种不同的角色:客户端和资源所有者。…资源所有者同意以后,资源服务器可以向客户端颁发令牌。客户端通过令牌,去请求数据。
四种获得令牌的流程:
-
授权码(authorization-code)
-
1.发送请求A->B
-
1
2
3
4
5https://b.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read -
A(客户端)->B()
response_type
参数表示要求返回授权码(code
),client_id
参数让 B 知道是谁在请求,redirect_uri
参数是 B 接受或拒绝请求后的跳转网址,scope
参数表示要求的授权范围(这里是只读)。
-
-
第二步,用户跳转后,B 网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 B 网站就会跳回
redirect_uri
参数指定的网址。跳转时,会传回一个授权码,就像https://a.com/callback?code=AUTHORIZATION_CODE
-
第三步,A 网站拿到授权码以后,就可以在后端,向 B 网站请求令牌。
-
1
2
3
4
5
6https://b.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL上面 URL 中,
client_id
参数和client_secret
参数用来让 B 确认 A 的身份(client_secret
参数是保密的,因此只能在后端发请求),grant_type
参数的值是AUTHORIZATION_CODE
,表示采用的授权方式是授权码,code
参数是上一步拿到的授权码,redirect_uri
参数是令牌颁发后的回调网址。
-
-
第四步,B 网站收到请求以后,就会颁发令牌。具体做法是向
redirect_uri
指定的网址,发送一段 JSON 数据。-
1
2
3
4
5
6
7
8
9{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101,
"info":{...}
}上面 JSON 数据中,
access_token
字段就是令牌,A 网站在后端拿到了。
-
-
-
隐藏式(implicit)
-
有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。
-
1
2
3
4
5https://b.com/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=readresponse_type
参数为token
,表示要求直接返回令牌。 -
https://a.com/callback#token=ACCESS_TOKEN``token
参数就是令牌,A 网站因此直接在前端拿到令牌。 -
▲注意,令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。
-
-
密码式(password):
-
如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。
-
-
客户端凭证(client credentials)
-
适用于没有前端的命令行应用,即在命令行下请求令牌。
-
clientID和ClientSecret均是App需要申请的API密钥
使用
Github Oauth
QQ Oauth
本地测试QQ的写法
1 | # 方法一:在hosts中将nymrli.top修改到127.0.0.1 |
坑点记录:部署
经过调试发现部署上去后,在http://beta.nymrli.top/info页面下获得不到
access_token = session.get('access_token')
于是猜想session设置有问题。果然linux下os.urandom(24)
有问题, 结果是无法获得到信息。经修改后能正常获得结果
1 | SECRET_KEY= os.urandom(24) # 设置为24位的字符,每次运行服务器都是不同的,所以服务器启动一次上次的session就清除。 |
改成随便的SECRET_KEY的就行了,比如SECRET_KEY='asdzxcqwe'
Author: Mrli
Link: https://nymrli.top/2019/06/03/Oauth2原理、使用/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.