OAuth含义
OAuth是一种授权机制,数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的令牌(token)用来代替密码,供第三方应用使用。
令牌和密码的作用是一样的,都可以进入系统,但有三点差异:
1.令牌是短期的,到期会自动失效,用户无法修改。密码一般长期有效,用户不修改,就不会发生变化。
2. 令牌可以被数据所有者撤销,会立即失效。
3. 令牌有权限范围,比如只能查看不能修改信息。密码一般是完整权限。
注意
:获取令牌后,就能根据令牌进入系统,一般不会再次确认身份,所以令牌必须保密,这也是为什么令牌的有效期设置的很短的原因。
OAuth授权方式介绍
OAuth2.0规定了四种获得令牌的流程:授权码(authorization-code)、隐藏式(implicit)、密码式(password)、客户端凭证(client credentials)。
注意
:不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。
第一种授权方式:授权码
介绍:第三方应用先申请一个授权码,然后再用该码获取令牌。
步骤:
- A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权B网站里的用户数据给 A 网站使用。
授权链接示例:
https://b.com/oauth/authorize?
response_type=code& //要求返回授权码
client_id=CLIENT_ID& //身份识别码,让B网站知道是谁在请求
redirect_uri=CALLBACK_URL& // A网站的回调地址,即B接受或拒绝请求后的跳转网址
scope=read //授权范围,read表示只读
- 第一步中,用户跳转到B网站后,B网站会要求用户登录,然后询问是否同意给予A网站授权。用户表示同意,这时B网站就会跳回redirect_uri参数指定的网址。跳转时会传回一个授权码(code),例:https://a.com/callback?code=AUTHORIZATION_CODE
- A网站拿到授权码之后就可以向B网站请求令牌
请求令牌示例:
https://b.com/oauth/token?
client_id=CLIENT_ID& //身份识别码,让B网站知道是谁在请求
client_secret=CLIENT_SECRET& //客户端密钥,需要保密,所以只能在后端发送请求
grant_type=authorization_code& //授权方式是授权码
code=AUTHORIZATION_CODE& //上一步拿到的授权码
redirect_uri=CALLBACK_URL //令牌颁发后的回调网址
- B网站收到请求以后,就会颁发令牌,一般返回参数是access token(访问token),refresh token(刷新token),expires_in(过期时间时长)
第二种方式:隐藏式
介绍:有些应用是纯前端应用,只能把令牌存储到前端,这个时候可以采取隐藏式,允许直接向前端颁发令牌,没有授权码这个中间步骤。
步骤:
- A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权B网站里的用户数据给 A 网站使用。
授权链接示例:
https://b.com/oauth/authorize?
response_type=token& //要求直接返回令牌
client_id=CLIENT_ID& //身份识别码,让B网站知道是谁在请求
redirect_uri=CALLBACK_URL& // A网站的回调地址,即B接受或拒绝请求后的跳转网址
scope=read //授权范围,read表示只读
- 第一步中,用户跳转到 B 网站,登录同意给予 A 网站授权。这时,B 网站就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 A 网站。例:https://a.com/callback
#
token=ACCESS_TOKEN。
需要注意的是,令牌的位置是URL锚点,而不是查询字符串,这是因为OAuth2.0允许跳转网址是http协议,因此存在“中间人攻击”的风险,而浏览器跳转的时候,锚点不会发到服务器,就减少了泄漏令牌的风险。
第三种方式:密码式
介绍:适用于高度信任的应用,通过用户名密码申请令牌
- A网站要求用户提供B网站的用户名和密码。拿到以后,A就直接向B请求令牌。
请求示例:
https://oauth.b.com/token?
grant_type=password& //授权方式是密码式
username=USERNAME&
password=PASSWORD&
client_id=CLIENT_ID
- B网站验证身份通过后,直接给出令牌。这时不需要跳转,而是把令牌放在JSON数据里面,作为HTTP回应,A拿到令牌。
第四种方式:凭证式
介绍:适用于没有前端的命令行应用,即在命令行下请求令牌。这种方式给出的令牌,是针对第三方应用的,而不是针对客户的,即有可能多个用户共享同一个令牌。
步骤:
- A应用在命令行向B发出请求。
请求示例:
https://oauth.b.com/token?
grant_type=client_credentials& //授权方式是凭证式
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
- B网站验证通过后,直接返回令牌。
刷新令牌
如果令牌有效期到了,此时让用户重新走一遍上面的流程,再申请一个新的令牌,那么体验不好,也没有必要。OAuth2.0允许用户自动更新令牌。
具体方法是,B网站在颁发令牌的时候就一次性颁发两个令牌,一个用于获取数据(accesstoken),一个用于获取新的令牌(refresh token)
刷新令牌示例:
https://b.com/oauth/token?
client_id=CLIENT_ID& //身份识别码,让B网站知道是谁在请求
client_secret=CLIENT_SECRET& //客户端密钥,需要保密,所以只能在后端发送请求
grant_type=refresh_token& //授权方式是刷新令牌
refresh_token=refresh_token //上一次授权获取的refresh_token