JWT是什么
JWT本质是Token,用于验证身份的凭证。这个凭证能允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
是经过base64编码字符串。
客户端(用户)通过用户名和密码进行身份认证,但是下回发请求的时候又得验证以下。
解决的办法是,用户成功登录之后,会在服务器端产生一条记录(Session),说明这用户是谁,然后把session_id传给客户端,并存入用户的Cookie。下次用户向服务器发送请求时,只需携带着包含用户信息的Cookie,看能否在服务器中找到记录,若可以则通过了身份认证,则把用户请求的数据返回到客户端。
上面提到的Session,会存储在服务器磁盘、内存或者数据库中,我们需要期清理过期的Session。
优点
- 可以主动清除session
- session保存在服务器端,相对较为安全
- 结合cookie使用,较为灵活,兼容性较好
缺点
服务器压力大:每个用户在认证后,Session 信息都会保存在服务器的内存中,开销大。
难以扩展:对于基于 Session 的分布式系统、集群,要实现负载均衡,需要做多机共享session机制,实现方法可将session存储到数据库中或者redis中,加大了对数据库额外的开销和维护。
会有跨域问题
JWT身份认证
为什么要使用Token?
- JWT本质是用于验证身份的凭证,这个凭证能允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
- 信息基于 base64 编码转换为 ASCII 码,字节占用很小,便于传输。
- 基于 Token 的鉴权机制保持了 HTTP 协议的无状态型,每次操作都会生成新的JWT,不需要在服务器端存储用户的记录,因此也没必要保存JWT,真正实现无状态,从而实现更简单的水平扩展。
- 客户端使用用户名和密码进行登录;
- 服务器端接收到请求后,取验证用户名和密码;
- 验证成功后,服务器会签发一个Token,再把Token签发到客户端;
- 客户端接收到Token之后,会存储到Cookie或者Local Storage;
- 客户端每次向服务器发出请求时,都要携带服务器端签发的Token;
- 服务器端接收到请求,去验证客户端携带的Token,如果验证成功,则返回客户端请求的数据。
Token的创建过程
JWT的Token由三部分组成:Header+Payload+Signature
1)Header 创建头部
Header 部分是一个 JSON 对象,描述 JWT 的元数据。
{
“alg”: “HS256”,
“typ”: “JWT”
}
alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(这个算法的密钥只有认证服务器和应用服务器知道),用什么 hash 算法来生成 JWT 签名模块(下文描述)。
typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。
2)Payload 创建负载
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。官方给出了json数据的字段。
{
“iss (issuer)”:签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
}
当然,我们也可以自定义。
{
“exp”: “1234567890”,
“username”: “test”
}
注意一点,payload 是一定不能够携带敏感数据如密码等信息的
3)Signature 签名
签名的目的主要是为了验证我是 “我“,把前两部分(Header、Payload)和用户的密钥进行哈希,防止数据篡改。换言之,即使Header或Payload被篡改,但篡改者不知到密钥是什么,无法生成签名,形成Token,服务器端无法通过验证。
生成签名的步骤:
①Base64URL对生成的 header 和 payload 进行 base64url编码,然后把编码生成的字符串中间通过句号(.)连接起来。
②把密钥secret和data进行hash算法加密,生成签名,再进行base64编码,生成签名。(此处的secret是指用户的密钥,通过HA256或者其他方法进行加密)
H
MACSHA256 ( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
延伸:
加密认证
JWT的签名除了通过密钥(secret)的HMAC加密算法,还支持公钥或私钥的RSA or ECDSA算法。
加密方法
- 对称加密:指的就是加、解密使用的同是一串密钥,所以被称做对称加密。对称加密只有一个密钥作为私钥。
常见的对称加密算法:DES,AES等。 - 非对称加密:指的是加、解密使用不同的密钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。反之,私钥加密的信息,只有公钥才能解密。 最常用的非对称加密算法:RSA
4)三个模块合并成Token
产生签名之后,把Header、Payload、Signature 三个部分用 “ . ” 拼成一个字符串。
自此,用户得到了服务器返回的Token(凭证)。用户下次登录的时候,在过期时间之内或者注销会话之内,可以凭这这个Token免密登录。
5.校验JWT
由于应用知道密钥,当用户向应用发起携带 JWT 的 API 请求时,应用可以执行签名算法。然后应用可以校验用户 hash 操作生成的签名是否和 JWT 中的签名匹配(即它匹配认证服务器创建的 JWT 签名),若匹配一致,则认证通过,返回请求的数据。
JWT适用场景
做简单的 Restful API 认证,从RESTful API查询使用JSON数据。RESTful API的原则之一是它应该是无状态的,这意味着当发出请求时,总会返回带有参数的响应,不会产生附加影响。
每次请求刷新 jwt。
缺点
JWT 本质上是通过时间换空间,服务器不存储用户状态信息,但是每个用户请求都会消耗 CPU 时间来验证 Token。
XSS攻击是恶意网页程序(通常是JavaScript)对网站进行攻击。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。
服务器返回的Token是存储在客户端的Cookie或者Local Storage中,故容易发生XSS攻击。
注意
为了防止中间人窃取Token,从而发生CSRF 攻击,使用https对请求进行加密传输。
JWT的信息是不加密存储的,不可存敏感信息。
设置一个表较短的过期时间。JWT是安全,但也不是绝对的,比如针对同一个接口,JWT字符串被截取后,且在有效期内,在不篡改JWT字符串的情况下,也是可以模拟请求进行访问的。颁发一个有效期极短的JWT,即使暴露了危险也很小。
生成签名字段时,支持使用密钥字符串签名(安全性较低),也支持使用 RSA、ECDSA 私钥签名。
https://juejin.im/entry/5bb211b7e51d450e5c478e0b