Oauth2.0学习记录
几乎每个系统,都不开身份验证,验证的方式也很多,Oauth2.0,SSO,还有最近新接触到的JWT,傻傻搞不清楚,他们之间到底是什么关系呢?
先简单整理一下Oauth2.0的内容,接下来继续学习SSO和JWT,继续完善,奥利给!
-
什么是Oauth2.0?
一种允许通过简单,标准的方法从Web,移动和桌面应用程序进行安全授权的开放协议。简单的说OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
-
什么是令牌(token)?与密码有什么不同?
- 令牌是有期限的,到期自动失效,且用户不能自己修改;密码一般长期有效,用户不修改就不会发生变化。
- 令牌可以被数据所有者撤销,立即失效;密码一般不允许被他人撤销。
- 令牌有权限范围,只能在有限范围内使用;密码一般没有限制。
在Oauth2.0中,令牌的颁发方式有四种,即四种授权类型。
-
四种授权类型
授权码(authorization-code),隐藏式(implicit),密码式(password),客户端凭证(client credentials)
以下说明的示例:A网站需要向B网站获取授权
第一种方式:授权码
这种方式是第三方应用先申请一个授权码,然后再用该码获取令牌,这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
过程:
-
A 网站提供一个链接,用户点击后就会跳转到 B 网站,
-
用户跳转后B 网站后会要求用户登录,然后询问是否同意给予 A 网站授权。若用户表示同意,则B网站会携带授权码跳回指定网址
-
A网站拿到授权码后,在后端向B网站请求令牌(token)
-
B网站颁发令牌,向指定网址传送一段JSON数据
{ "access_token":"ACCESS_TOKEN", "token_type":"bearer", "expires_in":2592000, "refresh_token":"REFRESH_TOKEN", "scope":"read", "uid":100101, "info":{...} }
第二种方式:隐藏式
有些 Web 应用是纯前端应用,没有后端,RFC 6749(OAuth 2.0 的标准)规定允许直接向前端颁发令牌,这种方式没有授权码。
过程:
- A 网站提供一个链接,用户点击后就会跳转到 B 网站,
- 用户跳转后B 网站后会要求用户登录,然后询问是否同意给予 A 网站授权。若用户表示同意,则B网站会携带令牌(token)跳回指定网址
- A网站在前端直接拿到token
这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
第三种方式:密码式
RFC 6749允许用户将用户名和密码告诉你高度信任的应用。
过程:
- A网站要求用户提供B网站的用户名和密码,拿到之后,A直接向B请求令牌
- B验证身份通过后,直接将令牌反正放在Json数据中返回给A。
这种方式风险很大,适用于其他方式都无法采用的情况。
第四种方式:凭证式
在命令行下请求令牌,适用于没有前端的命令行应用
过程:
- A 应用在命令行向 B 发出请求
- B 网站验证通过以后,直接返回令牌
这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
-
-
令牌的使用
在请求的头信息,加上一个
Authorization
字段,令牌就放在这个字段里面。比如A 网站拿到令牌以后,向 B 网站的 API 请求数据,每个请求,都必须带有令牌。
Authorization: Bearer ACCESS_TOKEN
-
令牌的更新
令牌是有有效期的,当令牌到期后,用户无需重新按照以上流程申请令牌,而是自动更新令牌。
具体方法是,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
参考链接:http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html