Jwt的使用

1.Jwt出现的原因及工作原理

1.1背景

在传统的会话管理方式中,服务器需要在每次请求时记录用户的会话状态,通常使用Session ID和Cookie来实现。然而,这种方式存在一些问题,如服务器需要维护会话状态,增加了服务器的负担;需要在多个服务器之间进行会话共享;不适用于跨域的场景

而JWT(JSON Web Token)是一种用于身份验证和授权的开放标准,它出现的原因是为了解决传统的会话管理方式的一些问题。

1.2工作原理

1.2.1

JWT的工作原理相对简单,它由三部分组成:头部(Header)、负载(Payload)和签名(Signature)。

  1. 头部(Header):头部通常由两部分组成,一部分是声明该令牌使用的加密算法(如HMAC、RSA等),另一部分是声明令牌的类型(即JWT)。
  2. 负载(Payload):负载是JWT的主要内容,包含了一些称为声明(claims)的信息,如用户ID、角色、过期时间等。负载可以根据需求自定义添加一些额外的信息。
  3. 签名(Signature):签名是为了验证令牌的真实性和完整性,防止令牌被篡改。签名使用头部、负载和一个密钥(只有服务器知道)进行加密生成,服务器在接收到令牌后使用相同的密钥进行解密和验证签名。

1.2.2

1)当用户进行身份验证时,服务器会生成一个JWT,并将其作为响应的一部分返回给客户端。
2)客户端在后续的请求中会在请求头或其他方式中携带该JWT。
3)服务器在接收到请求后,会使用相同的密钥解密和验证JWT的签名,从而确认JWT的真实性和完整性,并根据负载中的信息进行相应的身份验证和授权操作。

2.Jwt工具类介绍,三种场景

创建JWT令牌,签发事件为当前时间

	/**
	 * 创建JWT令牌,签发时间为当前时间
	 * 
	 * @param claims
	 *            创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
	 * @param ttlMillis
	 *            JWT的有效时间(单位毫秒),当前时间+有效时间=过期时间
	 * @return jwt令牌
	 */
	public static String createJwt(Map<String, Object> claims, 
			long ttlMillis) {
		// 生成JWT的时间,即签发时间 2021-10-30 10:02:00 -> 30 10:32:00
	
		long nowMillis = System.currentTimeMillis();

		
		//链式语法:
		// 下面就是在为payload添加各种标准声明和私有声明了
		// 这里其实就是new一个JwtBuilder,设置jwt的body
		JwtBuilder builder = Jwts.builder()
				// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
				.setClaims(claims)
				// 设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
				// 可以在未登陆前作为身份标识使用
				.setId(UUID.randomUUID().toString().replace("-", ""))
				// iss(Issuser)签发者,写死
				.setIssuer("zking")
				// iat: jwt的签发时间
				.setIssuedAt(new Date(nowMillis))
				// 代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可放数据{"uid":"zs"}。此处没放
				// .setSubject("{}")
				// 设置签名使用的签名算法和签名使用的秘钥
				.signWith(SIGNATURE_ALGORITHM, JWT_KEY)
				// 设置JWT的过期时间
				.setExpiration(new Date(nowMillis + ttlMillis));

		return builder.compact();
	}

测试
在这里插入图片描述

解密Jwt,获得所有声明(包括标准和私有声明)

	/**
	 * 解密jwt,获得所有声明(包括标准和私有声明)
	 * 
	 * @param jwt
	 * @return
	 * @throws Exception
	 */
	public static Claims parseJwt(String jwt) {
		Claims claims = Jwts.parser()
				.setSigningKey(JWT_KEY)
				.parseClaimsJws(jwt)
				.getBody();
		return claims;
	}

测试
在这里插入图片描述

复制Jwt,并重新设置签发时间

	/**
	 * 复制jwt,并重新设置签发时间(为当前时间)和失效时间
	 * 
	 * @param jwt
	 *            被复制的jwt令牌
	 * @param ttlMillis
	 *            jwt的有效时间(单位毫秒),当前时间+有效时间=过期时间
	 * @return
	 */
	public static String copyJwt(String jwt, Long ttlMillis) {
		//解密JWT,获取所有的声明(私有和标准)
		//old
		Claims claims = parseJwt(jwt);

		// 生成JWT的时间,即签发时间
		long nowMillis = System.currentTimeMillis();

		// 下面就是在为payload添加各种标准声明和私有声明了
		// 这里其实就是new一个JwtBuilder,设置jwt的body
		JwtBuilder builder = Jwts.builder()
				// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
				.setClaims(claims)
				// 设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
				// 可以在未登陆前作为身份标识使用
				//.setId(UUID.randomUUID().toString().replace("-", ""))
				// iss(Issuser)签发者,写死
				// .setIssuer("zking")
				// iat: jwt的签发时间
				.setIssuedAt(new Date(nowMillis))
				// 代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可放数据{"uid":"zs"}。此处没放
				// .setSubject("{}")
				// 设置签名使用的签名算法和签名使用的秘钥
				.signWith(SIGNATURE_ALGORITHM, JWT_KEY)
				// 设置JWT的过期时间
				.setExpiration(new Date(nowMillis + ttlMillis));
		return builder.compact();
	}

测试
在这里插入图片描述
在这里插入图片描述

3.Jwt与Vuex配合在SPA项目中的应用

步骤

1)user登录方法,要放开用户信息生成jwt串保存到响应头中的代码

2)关闭jwtfilter中的off开关,代表开启jwt验证

private boolean OFF = false;// true关闭jwt令牌验证功能

3)crosfilter中要允许jwt使用请求头及响应头

 <!--CrosFilter跨域过滤器-->
  <filter>
    <filter-name>corsFilter</filter-name>
    <filter-class>com.zking.ssm.util.CorsFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>corsFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

state.js

export default{
	jwt: ''
}

mutations.js

export default{
   setJwt:function(state,payload){
	// 载荷
	staet.jwt = payload.jwt;
	} 
}

getters.js

export default{
	getJwt:function(state){
		return state:jwt;
	}
}

main.js

window.vm = new Vue({})

http.js

// 请求拦截器
axios.interceptors.request.use(function(config) {
	var jwt = window.vm.$store.getters.getJwt;
	config.headers['jwt'] = jwt;
	return config;
}, function(error) {
	return Promise.reject(error);
});

// 响应拦截器
axios.interceptors.response.use(function(response){
	var jwt = response.headers['jwt'];
	if(jwt){
		window.vm.$store.commit('setJwt',{jwt:jwt});
	}
	return response;
}, function(error) {
	return Promise.reject(error);
})

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值