这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战
授权码
授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌(适合前后端分离,最常用的方式)。
这种方式是最常用的流程,安全性也最高,它适用于有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
实现流程
-
A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。
https://b.com/oauth/authorize? response_type=code& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read 复制代码
- response_type=code code参数表示要求返回授权码
- client_id=CLIENT_ID 参数让B知道是谁在请求数据
- redirect_uri = CALLBACK_URL 当B网站处理完成链接请求后的跳转地址
- scope=read 表示要授权的范围,read代表对授权资源进行只读操作
-
跳转成功,B 网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 B 网站就会跳回
redirect_uri
参数指定的网址。跳转时,会传回一个授权码https://a.com/callback?code=AUTHORIZATION_CODE // code 代表授权码 复制代码
-
A 网站拿到授权码以后,就可以在后端,向 B 网站请求令牌。
https://b.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL
复制代码
client_id 确认A的身份
client_secret 确认A的身份
grant_type 表示使用授权的方式获取授权码
code 第二步中获取到的code值
redirect_uri 令牌颁发后的回调地址
- B 网站收到请求以后,就会颁发令牌。具体做法是向
redirect_uri
指定的网址,发送一段 JSON 数据。
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101,
"info":{...}
}
复制代码
隐藏式
适用于纯前端的WEB应用,必须将令牌储存在前端。允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。由于前端直接获取token,安全性较低,一般适用于比较信任的网站,并且令牌的有效期,也相对较短,一般是界面关闭及失效
实现流程
-
A 网站提供一个链接,要求用户跳转到 B 网站,授权用户数据给 A 网站使用
https://b.com/oauth/authorize? response_type=token& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read 复制代码
response_type=token 表示直接返回令牌
-
用户跳转到 B 网站,登录后同意给予 A 网站授权。B 网站就会跳回
redirect_uri
参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。https://a.com/callback#token=ACCESS_TOKEN 复制代码
token参数为令牌,令牌的位置是 URL 锚点(fragment),而不是查询字符串(querystring),这是因为 OAuth 2.0 允许跳转网址是 HTTP 协议,因此存在"中间人攻击"的风险,而浏览器跳转时,锚点不会发到服务器,就减少了泄漏令牌的风险。