最近的项目需要用到OAuth2.0认证,总结一下最常用的授权码方式。
参考网址:
http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
https://www.cnblogs.com/kaleidoscope/p/9507261.html
第一步:请求授权码
A网站提供连接,用户点击后跳转到B网站,此时会授权用户数据给A网站使用。
https://b.com/oauth/authorize? response_type=code& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read& state=xyz
response_type:授权类型,必选,固定“code”,表示要求返回授权码。
client_id:客户端id,必选,表示请求方是谁。
redirece_uri:重定向uri,可选,表示B处理请求后的跳转网址。
scope:申请的权限范围,可选,这里用的只读。
state:客户端当前状态,可选,可以指定任意值,B会原封不动返回这个值。
第二步:返回授权码
用户跳转到B网站后,网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,此时,B网站就会跳到redirece_uri参数指定的网址。跳转时,会传递一个授权码
https://a.com/callback?code=AUTHORIZATION_CODE
code:表示授权码
第三步:请求令牌
A网站得到B传递的授权码,就可以在后端,向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:同第一步,为客户端id,必选,表示身份。
client_secret:客户端秘钥,可选,为保密数据,因此只能是在后端发请求。
grant_type:授权方式,必选,表示采用的授权方式,authorization_code为授权码方式。
-
authorization_code — 授权码模式(即先登录获取code,再获取token)
-
password — 密码模式(将用户名,密码传过去,直接获取token)
-
client_credentials — 客户端模式(无用户,用户向客户端注册,然后客户端以自己的名义向’服务端’获取资源)
-
implicit — 简化模式(在redirect_uri 的Hash传递token; Auth客户端运行在浏览器中,如JS,Flash)
-
refresh_token — 刷新access_token
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":{...}
}
access_token:颁发的令牌。
token_type:表示令牌的类型。bearer或者mac
expires_in:过期时间,单位为秒,如果省略该参数,必须以其他方式设置过期时间。
refresh_token:更新令牌,可选,用来获取下一次的访问令牌。
scope:权限范围,如果与第一步的权限相同,可省略。
------
令牌的使用
A 网站拿到令牌以后,就可以向 B 网站的 API 请求数据了。
此时,每个发到 API 的请求,都必须带有令牌。具体做法是在请求的头信息,加上一个`Authorization`字段,令牌就放在这个字段里面。
curl -H "Authorization: Bearer ACCESS_TOKEN" \
"https://api.b.com"
ACCESS_TOKEN:拿到的令牌。
------
更新令牌
OAuth 2.0 允许用户自动更新令牌。令牌到期时
具体方法是,B 网站颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。
https://b.com/oauth/token?
grant_type=refresh_token&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
refresh_token=REFRESH_TOKEN
grant_type:refresh_token表示要求更新令牌。
client_id & client_secret:确认身份。
refresh_token:用于更新令牌的令牌。