概述
概述
简介
JWT是一种用于双方之间传递安全信息的简洁的、URL安全的声明规范。
定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。
特别适用于分布式站点的单点登录(SSO)场景
传统的session认证的缺点
安全性:CSRF攻击因为基于cookie来进行用户识别, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。
扩展性:对于分布式应用,需要实现 session 数据共享
性能:每一个用户经过后端应用认证之后,后端应用都要在服务端做一次记录,以方便用户下次请求的鉴别, 通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大
使用方式
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage,此后,客户端每次与服务器通信,都要带上这个JWT。 可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
结构
头部header
{ "alg": "HS256", "typ": "JWT" } alg属性表示签名的算法,默认是 HMAC SHA256(写成 HS256 typ属性表示这个令牌(token)的类型(type),统一写为 JWT
载荷payload
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 } 内容又可以分为3中标准:标准中注册的声明/公共的声明/私有的声明 1.payload-标准中注册的声明 (建议但不强制使用): iss: jwt签发者 sub: jwt所面向的用户 aud: 接收jwt的一方 exp: jwt的过期时间,这个过期时间必须要大于签发时间 nbf: 定义在什么时间之前,该jwt都是不可用的. iat: jwt的签发时间 jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 2.payload-公共的声明 : 公共的声明可以添加任何的信息。一般这里我们会存放一下用户的基本信息(非敏感信息) 3.payload-私有的声明 : 私有声明是提供者和消费者所共同定义的声明。需要注意的是,不要存放敏感信息!!!
签证signature
这部分就是 JWT 防篡改的精髓,其值是对前两部分base64UrlEncode 后使用指定算法签名生成 以默认 HS256 为例,指定一个密钥(secret),就会按照如下公式生成: HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret, )
最后一步
算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户
工具类
工具类【普通版】
功能
1.生成令牌
2.校验令牌并返回true或fals
代码
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import java.util.Date;
/**
* JWT工具类
*/
public class JWTUtil {
//签发人
private static final String ISS_USER = "jkw";
//令牌过期时间(五分钟)
private static final long TOKEN_EXPIRE_TIME = 5 * 60 * 1000;
//秘钥(最好写的复杂一点)
private static final String KEY = "jkw-123456";
/**
* 生成令牌
*
* @return
*/
public static String token() {
Date now = new Date();//时间
Algorithm algorithm_key = Algorithm.HMAC256(KEY);//加密秘钥
//创建JWT
String token = JWT.create()
//签发人
.withIssuer(IS