理解OAuth2.0
OAuth2.0是什么?
OAuth2.0是方便给第三方应用程序授权的标准授权协议(RFC749),注意是授权协议(authentication ),不是认证(authorization).
OAuth2.0相关名词定义
- Resource Owner: 资源拥有者,也就是一般用户
- Third-party Application: 第三方应用
- User Agent: 用户代理,可以是浏览器等
- Authorization server: 认证服务器
- Resource server: 资源服务器,一般是Api接口,等等需要被保护的资源.
理解OAuth2.0
OAuth2.0的应用是很广泛的,作为开发者可以
- 可以将自己的应用程序作为微信第三方客户端接入,获取用户拥有者在微信的头像,性别,等用户信息
- 结合时下流行的SpringCloud,搭建授权服务器,资源服务器,为分布式服务做统一的认证
下面理解下流程最完善的的授权码模式, 其他模式就很好理解了.
1.资源拥有者(即用户),使用浏览器(客户端代理)访问第三方应用(SPA),SPA将资源拥有者导向认证中心
[GET] /uaa/authorize?
response_type=code
&client_id=s6BhdRkqt3
&state=mark
&redirect_uri=www.client.example.com/xx
参数解释
response_type: 表示授权类型,必选,授权码模式这步固定为"code"
client_id: 表示客户端的ID,必选
redirect_uri: 表示重定向的url,可选
scope: 表示申请选项的范围,可选
state: 表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值(可以标记页面位置)
假设用户登录认证中心,并且授权第三方客户端的请求
则UAA跳转到redirect_uri并且附加授权码
http://client.example.com/xx
?code=12345
&state=mark
2.前端服务器从回调地址中获取授权码并且携带存储在前端服务器的client_secret,到认证中心获取令牌.
这个步骤在后台完成对用户不可见.
注意客户端密钥不能放在浏览器(用户代理),因为这样是不安全的,应该放在客户端的后台服务器.
[POST]
/uaa/authorize
grant_type=authorization_code
&code=12345
&redirect_uri=https://client.example.com/xx
参数说明
参数说明:
response_type: 表示授权类型,必选,授权码模式这步固定为"authorization_code",必选
code: 授权码,必选
redirect_uri: 重定向URL,必选
client_id: 客户端ID.必选
3.认证服务器核对授权码和回调地址,颁发令牌
令牌的样式和存储方式是多种多样的,可以存放在Redis中,也可以是不需要后台存储的JWT令牌
{
"access_token":"123456",
"token_type":"example",
"expires_in":3600,
"refresh_token":"654321",
}
4.第三方应用携带令牌访问资源服务器,资源服务器携带令牌去授权服务器,验证权限通过,则可以访问资源。
思考
1.资源服务器每次都需要和UAA交互,验证令牌,这样是否影响性能?
每次调用资源服务器的API,都需要资源服务器和认证中心验证令牌,可不可以优化?
使用JWT令牌,资源服务器自身使用密钥校验令牌的是否正确.(JWT防篡改,但是不加密安全的)
2.使用JWT有没有其他问题?
使用JWT,减轻了压力,但是JWT令牌在有效期内,无法销毁,无法强制用户下线,或者但设备登录,因此需要权衡业务背景
3. 结合OAuth2.0 如何做单点登录
多个SPA在将用户导向认证中心时,SPA维护与Node的session粘性,前端服务器在此维护与认证中心uua.com的session粘性,即可实现单点登录
参考:
(RFC6749)https://datatracker.ietf.org/doc/html/rfc6749
(OAuth2.0)https://oauth.net/2/
(OAuth2.0)https://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html