为什么?
单一架构 演变到 分布式集群项目 需要解决session共享问题
SSO(Single Sign On)模式
CAS单点登录、OAuth2
- 如图所示 图中有三个系统 分别为业务A B 和SSO
- 业务A 和 B 没有登录模块
- 只有SSO有登录模块 没有其他的业务模块
一般过程:
- 当业务A B 需要登录的时候 跳转到 SSO系统
- SSO从用户信息数据库中 获取用户信息 并且 校验 校验通过 SSO完成登录
- 将校验的用户信息存入缓存(如:redis)
- 当用户访问其他业务时 如果需要登录 将跳转到SSO系统中 进行用户身份认证 SSO判断缓存中是否存在用户身份信息
- 只要在其中一个业务中 完成了 用户登录 其他的应用系统 都不需要登录
优点:
用户身份信息独立管理,更好的分布式管理。可以自己扩展安全策略
缺点:
认证服务器访问压力较大。
Token模式
优点:
- 无状态:token是无状态的 session是有状态的
- 基于标准化 :API是基于标准化 JSON Web Token(JWT)
缺点:
- 占用带宽
- 无法在服务器端销毁
访问令牌的类型
JWT令牌
是什么?
JWT 是JSON Web Token的缩写 即:JSON Web令牌 是一种自包含令牌
使用场景
- 一种情况:web API 类似于 阿里云播放凭证功能
- 另一种情况 多web服务器下 实现 无状态 分布式 身份验证
JWT的作用
- JWT最重要的作用 就是对 token 信息的防伪作用
JWT的原理
- 一个JWT由 三个 部分组成 :JWT头 有效载荷 签名哈希
- 最后由这三者 组合 进行base64 编码 得到 JWT
JWT 令牌的组成
- 令牌的三部分 每个部分通过 “.” 分割 成为三个子串
- 每个子串代表一个功能块 总共三个部分 JWT头 有效载荷 签名
JWT 头
头部分 是一个 描述 JWT 元数据 的 JSON 对象
1
2
3
4 {
"alg": "HS256",
"typ": "JWT"
}在上面的代码中,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存。
有效载荷
有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择。
1
2
3
4
5
6
7 iss: jwt签发者
sub: 主题
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。除以上默认字段外,我们还可以自定义私有字段,如下例:
1
2
3
4
5 {
"name": "Helen",
"admin": true,
"avatar": "helen.jpg"
}请注意,默认情况下JWT是未加密的,任何人都可以解读其内容,因此不要构建隐私信息字段,存放保密信息,以防止信息泄露。
JSON对象也使用Base64 URL算法转换为字符串保存。
签名哈希
签名哈希部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。
首先,需要指定一个密码(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名。
1 HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(claims), secret) ==> 签名hash在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用”.”分隔,就构成整个JWT对象。
Base64URL算法
如前所述,JWT头和有效载荷序列化的算法都用到了Base64URL。该算法和常见Base64算法类似,稍有差别。
作为令牌的JWT可以放在URL中(例如api.example/?token=xxx)。 Base64中用的三个字符是”+”,”/“和”=”,由于在URL中有特殊含义,因此Base64URL中对他们做了替换:”=”去掉,”+”用”-“替换,”/“用”_”替换,这就是Base64URL算法。
注意:base64编码,并不是加密,只是把明文信息变成了不可见的字符串。但是其实只要用一些工具就可以把base64编码解成明文,所以不要在JWT中放入涉及私密的信息。
JWT的用法
客户端接收服务器返回的JWT,将其存储在Cookie或localStorage中。
此后,客户端将在与服务器交互中都会带JWT。如果将它存储在Cookie中,就可以自动发送,但是不会跨域,因此一般是将它放入HTTP请求的Header Authorization字段中。
当跨域时,也可以将JWT放置于POST请求的数据主体中。
JWT 的 问题 和 趋势
- JWT默认不加密,但可以加密。生成原始令牌后,可以使用该令牌再次对其进行加密。
- 当JWT未加密时,一些私密数据无法通过JWT传输。
- JWT不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数。
- JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦JWT签发,在有效期内将会一直有效。
- JWT本身包含认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。为了减少盗用,JWT的有效期不宜设置太长。对于某些重要操作,用户在使用时应该每次都进行身份验证。
- 为了减少盗用和窃取,JWT不建议使用HTTP协议来传输代码,而是使用加密的HTTPS协议进行传输。