所谓JWT也就是json web token,现在多用于用户认证。
传统的cookie加session认证流程如下:
1.用户输入账号密码,发送给服务器
2.服务器验证账号密码成功后,创建一个会话(Session),同时将这个会话(Session)的SessionID存于客户端(Cookie)中,然后cookie将随着response返回到客户端。一般情况的SessionID包含了浏览器信息以及session所属服务器下的web应用信息。实现代码如下
注意:这里使用request.getSession()创建session时,会先检查request中的cookie是否包含JSESSIONID(这个应该是web容器里面实现的),当不存在JSESSIONID时认为这个是第一次请求,创建新的会话(session);如果request中的cookie包含JSESSIONID,则直接从内存中获取对应session。
3.后续的请求中,浏览器会发送会话 ID 到服务器,服务器上如果能找到对应 ID 的会话,那么服务器就会返回需要的数据给浏览器
4.当用户退出登录,会话会同时在客户端和服务器端被销毁
这种认证方式的不足之处有两点
1、服务器端要为每个用户保留 session 信息,连接用户多了,服务器内存压力巨大
2、不适合分布式
JWT包含了使用.分隔的三部分: Header 头部 Payload 负载 Signature 签名
其结构看起来是这样的Header.Payload.Signature
Header
在header中通常包含了两部分:token类型和采用的加密算法。{ "alg": "HS256", "typ": "JWT"} 接下来对这部分内容使用 Base64Url 编码组成了JWT结构的第一部分。
Payload
Token的第二部分是负载,它包含了claim, Claim是一些实体(通常指的用户)的状态和额外的元数据,有三种类型的claim:reserved, public 和 private.Reserved claims: 这些claim是JWT预先定义的,在JWT中并不会强制使用它们,而是推荐使用,常用的有 iss(签发者),exp(过期时间戳), sub(面向的用户), aud(接收方), iat(签发时间)。 Public claims:根据需要定义自己的字段,注意应该避免冲突 Private claims:这些是自定义的字段,可以用来在双方之间交换信息 负载使用的例子:{ "sub": "1234567890", "name": "John Doe", "admin": true} 上述的负载需要经过Base64Url编码后作为JWT结构的第二部分。
Signature
创建签名需要使用编码后的header和payload以及一个秘钥,使用header中指定签名算法进行签名。例如如果希望使用HMAC SHA256算法,那么签名应该使用下列方式创建: HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 签名用于验证消息的发送者以及消息是没有经过篡改的。 完整的JWT 完整的JWT格式的输出是以. 分隔的三段Base64编码,与SAML等基于XML的标准相比,JWT在HTTP和HTML环境中更容易传递。 下列的JWT展示了一个完整的JWT格式,它拼接了之前的Header, Payload以及秘钥签名:
----------------------2019.12.16------------------------
公众号中看到的几种攻击方式 ,其中有两种是我之前不知道的,补充上来,备忘
https://mp.weixin.qq.com/s/BH-gmMpHUkMvBcSBgJWnwA