JWT
JSON Web Token(JWT)跨域身份验证解决方案
跨域身份验证
身份验证的过程如下:
- 用户向服务器发送用户名和密码
- 验证服务器后,相关的数据如用户角色,登录时间等会保存在当前会话中
- 服务器向用户返回session_id,session信息都会写入到用户的Cookie中
- 用户的每一个后续请求都会通过在Cookie中取得session_id传给服务器
- 服务器收到session_id并与之前保存的数据进行对比,确认用户的身份
这样只能够在单一服务器上使用。
单点登录需求:站点A和站点B提供相关的服务,用户登录其中一个站点,就会自动登录另一个站点
一种实现方式是将session持久化,收到请求后验证服务从持久层拿数据来处理
另一种实现方式:服务器不保存会话数据,而是通过客户端保存数据,每个请求都会发送回服务器,如JWT
JWT的原则
JWT的原则是在服务器身份验证后,生成一个JSON对象并发送给用户,如下所示:
{ "UserName": "Chongchong", "Role": "Admin", "Expire": "2018-08-08 20:15:56" }
之后当用户再与服务器通信时,会在请求中发回这个JSON对象,服务器依赖这个JSON对象来标识用户。为了防止用户篡改数据,服务器在生成对象时还会添加签名。这样服务器不用保存任何会话数据变成无状态的。
JWT数据结构
JWT对象是一个很长的字符串,字符间通过“.”分隔符分割为3个子串,三部分分别为JWT头,有效载荷和签名
JWT头
JWT头是一个描述JWT元数据的JSON对象,表示如下
{ "alg": "HS256", "typ": "JWT" }
alg属性表示签名使用的算法,typ属性表示令牌的类型,最后使用Base64URL算法将该JSON对象转换为字符串保存
有效载荷
有效载荷是JWT的主体部分,也是一个JSON对象,包含要传递的数据,有七个默认字段供选择
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT
也可以自定义字段,JWT默认情况是未加密的。该对象也用Base64 URL算法转换为字符串保存
签名哈希
签名哈希是对上面两个部分的签名,通过指定的算法生成哈希,来确保数据不会被篡改,要指定一个密码,仅仅保存在服务器中,不向用户公开,HMACSHA256签名算法的公式
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret)
Base64URL算法
JWT令牌可以放在URL中,由于"+","/","="在URL中有特殊含义,所以Base64URL中对它们进行了替换,"="去掉,"+"用"-"替换,"/"用"_"替换
JWT的用法
客户端在接收服务器返回的JWT后,将其存储在Cookie或loclStorage中,之后,客户端与服务器交互都会带JWT,如果JWT存储在Cookie中就能自动发送但是不会跨域,因此一般将其放在HTTP请求的Header Authorization字段中。也可以将其放置在Post请求中。