一.什么是JWT
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用间安全地传递信息。它是一种紧凑的、自包含的方式,用于在用户和服务之间以 JSON 对象的形式安全地传输信息。
JWT 主要由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。头部(Header)包含了关于令牌类型和签名算法的元数据,通常包含两部分信息,令牌的类型(即 "JWT")和所使用的哈希算法(例如 HMAC SHA256 或 RSA)。载荷(Payload)包含了要传输的信息,以及其他元数据。载荷被编码成 JSON 对象,并包含了称为声明(claims)的键值对。声明分为三种类型:注册声明(Registered claims):这些是预定义的声明,包括标准的声明(比如:iss(签发者)、sub(主题)、exp(到期时间)、aud(受众)等)。公共声明(Public claims):这些是自定义的声明,用于自由定义你自己的声明内容。私有声明(Private claims):这些是自定义的声明,但是它们的名字应该是唯一的,以防止冲突。
利用token
进行用户身份验证的流程:
1.客户端使用用户名和密码请求登录
2.服务端收到请求,验证用户名和密码
3.验证成功后,服务端会签发一个token,再把这个token返回给客户端
4.客户端收到token后可以把它存储起来,比如放到cookie中
5.客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带
6.服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据
而JWT就是上述流程当中token的一种具体实现方式,其全称是JSON Web Token,官网地址:https://jwt.io/,通俗地说,JWT的本质就是一个字符串,它是将用户信息保存到一个Json字符串中,然后进行编码后得到一个JWT token,并且这个JWT token带有签名信息,接收后可以校验是否被篡改,所以可以用于在各方之间安全地将信息作为Json对象传输。
二.使用JWT
1.导入依赖
2.生成token
3.解析JWT
三.为什么用JWT
1.传统的session认证有以下弊端:
- 每个用户的登录信息都会保存到服务器的session中,随着用户的增多,服务器开销会明显增大
- 由于session是存在与服务器的物理内存中,所以在分布式系统中,这种方式将会失效。虽然可以将session统一保存到Redis中,但是这样做无疑增加了系统的复杂性,对于不需要redis的应用也会白白多引入一个缓存中间件
- 对于非浏览器的客户端、手机移动端等不适用,因为session依赖于cookie,而移动端经常没有cookie 因为session认证本质基于cookie,所以如果cookie被截获,用户很容易收到跨站请求伪造攻击。并且如果浏览器禁用了cookie,这种方式也会失效
- 前后端分离系统中更加不适用,后端部署复杂,前端发送的请求往往经过多个中间件到达后端,cookie中关于session的信息会转发多次
- 由于基于Cookie,而cookie无法跨域,所以session的认证也无法跨域,对单点登录不适用
2.JWT的优势:
- 简洁:JWT Token数据量小,传输速度也很快
- 因为JWT Token是以JSON加密形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持
- 不需要在服务端保存会话信息,也就是说不依赖于cookie和session,所以没有了传统session认证的弊端,特别适用于分布式微服务
- 单点登录友好:使用Session进行身份认证的话,由于cookie无法跨域,难以实现单点登录。但是,使用token进行认证的话, token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie,不会存在这些问题
- 适合移动端应用:使用Session进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到Cookie(需要 Cookie 保存 SessionId),所以不适合移动端
四.JWT结构
JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.
进行连接形成最终传输的字符串
1.Header
JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存
2.Payload
有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择
3.Signature
签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名