IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> jwt * -> 正文阅读

[网络协议]jwt *

?目录

?一、jwt出现的原因及工作原理?

1. JWT是什么

2. 为什么使用JWT

3. JWT的工作原理

4、jwt解决不需要登录就能直接访问的问题:?

解决登录后树形菜单未出现的问题?:

二、jwt工具类介绍,三种场景

1、jwt工具类

2、三种场景

三、jwt与vuex配合在SPA项目中的应用


目标:

①、jwt出现的原因及工作原理
②、jwt工具类介绍,三种场景
③、jwt与vuex配合在SPA项目中的应用

?一、jwt出现的原因及工作原理?

1. JWT是什么

JSON Web Token (JWT),它是目前最流行的跨域身份验证解决方案

2. 为什么使用JWT

JWT的精髓在于:“去中心化”,数据是保存在客户端的。

3. JWT的工作原理

? ?①. 是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户,示例如下:
? ? ? {"UserName": "Chongchong","Role": "Admin","Expire": "2018-08-08 20:15:56"}

? ?②. 之后,当用户与服务器通信时,客户在请求中发回JSON对象
? ??
? ?③. 为了防止用户篡改数据,服务器将在生成对象时添加签名,并对发回的数据进行验证

传统开发对资源的访问限制利用session完成图解:

jwt所解决的问题及机制:

4、jwt解决不需要登录就能直接访问的问题:?

不需要登录就能直接访问(不合理):

①、web.xml:解决jwt问题的过滤器

<!-- 解决jwt问题的过滤器 -->
?? ?<filter>
?? ??? ?<filter-name>jwtFilter</filter-name>
?? ??? ?<filter-class>com.zking.vue.util.JwtFilter</filter-class>
?? ?</filter>
?? ?<filter-mapping>
?? ??? ?<filter-name>jwtFilter</filter-name>
?? ??? ?<url-pattern>/*</url-pattern>
?? ?</filter-mapping>

②、JwtFilter.java:开启jwt令牌验证功能

package com.zking.vue.util;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import io.jsonwebtoken.Claims;

/**se
?* * JWT验证过滤器,配置顺序 :CorsFilte-->JwtFilter-->struts2中央控制器
?*?
?* @author Administrator
?*
?*/
public class JwtFilter implements Filter {

?? ?// 排除的URL,一般为登陆的URL(请改成自己登陆的URL)
?? ?private static String EXCLUDE = "^/vue/userAction_login\\.action?.*$";

?? ?private static Pattern PATTERN = Pattern.compile(EXCLUDE);

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

?? ?@Override
?? ?public void init(FilterConfig filterConfig) throws ServletException {
?? ?}

?? ?@Override
?? ?public void destroy() {
?? ?}

?? ?@Override
?? ?public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
?? ??? ??? ?throws IOException, ServletException {
?? ??? ?HttpServletRequest req = (HttpServletRequest) request;
?? ??? ?HttpServletResponse resp = (HttpServletResponse) response;
?? ??? ?String path = req.getServletPath();
?? ??? ?if (OFF || isExcludeUrl(path)) {// 登陆直接放行
?? ??? ??? ?chain.doFilter(request, response);
?? ??? ??? ?return;
?? ??? ?}

?? ??? ?// 从客户端请求头中获得令牌并验证
?? ??? ?String jwt = req.getHeader(JwtUtils.JWT_HEADER_KEY);
?? ??? ?Claims claims = this.validateJwtToken(jwt);
?? ??? ?if (null == claims) {
?? ??? ??? ?// resp.setCharacterEncoding("UTF-8");
?? ??? ??? ?resp.sendError(403, "JWT令牌已过期或已失效");
?? ??? ??? ?return;
?? ??? ?} else {
?? ??? ??? ?String newJwt = JwtUtils.copyJwt(jwt, JwtUtils.JWT_WEB_TTL);
?? ??? ??? ?resp.setHeader(JwtUtils.JWT_HEADER_KEY, newJwt);
?? ??? ??? ?chain.doFilter(request, response);
?? ??? ?}
?? ?}

?? ?/**
?? ? * 验证jwt令牌,验证通过返回声明(包括公有和私有),返回null则表示验证失败
?? ? */
?? ?private Claims validateJwtToken(String jwt) {
?? ??? ?Claims claims = null;
?? ??? ?try {
?? ??? ??? ?if (null != jwt) {
?? ??? ??? ??? ?claims = JwtUtils.parseJwt(jwt);
?? ??? ??? ?}
?? ??? ?} catch (Exception e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ??? ?return claims;
?? ?}

?? ?/**
?? ? * 是否为排除的URL
?? ? *?
?? ? * @param path
?? ? * @return
?? ? */
?? ?private boolean isExcludeUrl(String path) {
?? ??? ?Matcher matcher = PATTERN.matcher(path);
?? ??? ?return matcher.matches();
?? ?}

?? ?// public static void main(String[] args) {
?? ?// String path = "/sys/userAction_doLogin.action?username=zs&password=123";
?? ?// Matcher matcher = PATTERN.matcher(path);
?? ?// boolean b = matcher.matches();
?? ?// System.out.println(b);
?? ?// }

}

③、UserAction .java:将jwt令牌塞入响应头

package com.zking.vue.web;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.opensymphony.xwork2.ModelDriven;
import com.zking.base.web.BaseAction;
import com.zking.vue.biz.UserBiz;
import com.zking.vue.entity.User;
import com.zking.vue.util.JsonData;
import com.zking.vue.util.JwtUtils;
import com.zking.vue.util.PageBean;
import com.zking.vue.util.ResponseUtil;
import com.zking.vue.util.StringUtils;
public class UserAction extends BaseAction implements ModelDriven<User>{
	private UserBiz userBiz;
	private User user = new User();
	public UserBiz getUserBiz() {
		return userBiz;
	}
	public void setUserBiz(UserBiz userBiz) {
		this.userBiz = userBiz;
	}
	public String login() {
		ObjectMapper om = new ObjectMapper();
		JsonData jsonData = null;
		try {
			if(StringUtils.isBlank(user.getUname()) || StringUtils.isBlank(user.getPwd())) {
				jsonData = new JsonData(0, "用户或者密码为空", user);
			}else {
				User u = this.userBiz.login(user);
				Map<String, Object> claims = new HashMap<String, Object>();
				claims.put("uname",user.getUname());
				claims.put("pwd", user.getPwd());
				String jwt = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);
				response.setHeader(JwtUtils.JWT_HEADER_KEY, jwt);
				jsonData = new JsonData(1, "登录成功", u);
			}
		} catch (Exception e) {
			e.printStackTrace();
			jsonData = new JsonData(0, "用户或者密码错误", user);
		}finally {
			try {
				ResponseUtil.write(response, om.writeValueAsString(jsonData));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	public String getAsyncData() {
		ObjectMapper om = new ObjectMapper();
		try {
			Thread.sleep(6000);
			ResponseUtil.write(response, om.writeValueAsString("http://www.javaxl.com"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	@Override
	public User getModel() {
		return user;
	}
}

④、界面展示

因为没有登录,所有看不到左侧树形菜单?

?并且报出403错误

403错误出现的原因:

? ? ? ? ①被限制了,限制了访问,没有拿到凭证;

? ? ? ? ②做爬虫的时候也会出现,IP被封了,没有凭证;

? ? ? ? ③被拉入黑名单了;

解决登录后树形菜单未出现的问题?:

①、jwt令牌:

jwt令牌响应头在浏览器中,前端代码并未获得

http.js?拿到所有的响应头信息

/**
?* vue项目对axios的全局配置
?*/
import axios from 'axios'
import qs from 'qs'
//引入action模块,并添加至axios的类属性urls上
import action from '@/api/action'
axios.urls = action
// axios默认配置
axios.defaults.timeout = 10000; // 超时时间
// axios.defaults.baseURL = 'http://localhost:8080/j2ee15'; // 默认地址
axios.defaults.baseURL = action.SERVER;
//整理数据
// 只适用于 POST,PUT,PATCH,transformRequest` 允许在向服务器发送前,修改请求数据
axios.defaults.transformRequest = function(data) {
?? ?data = qs.stringify(data);
?? ?return data;
};
// 请求拦截器
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) {
?? ?//debugger;
? /* 拿到所有的响应头信息*/
?? ?var jwt = response.headers['jwt'];
?? ?if(jwt){?
// 通过mutations进行值得设置
?? ??? ?window.vm.$store.commit('setJwt',{jwt:jwt});
?? ?}
?? ?return response;
}, function(error) {
?? ?return Promise.reject(error);
});

// // 路由请求拦截
// // http request 拦截器
// axios.interceptors.request.use(
// ?? ?config => {
// ?? ??? ?//config.data = JSON.stringify(config.data);
// ?? ??? ?//config.headers['Content-Type'] = 'application/json;charset=UTF-8';
// ?? ??? ?//config.headers['Token'] = 'abcxyz';
// ?? ??? ?//判断是否存在ticket,如果存在的话,则每个http header都加上ticket
// ?? ??? ?// if (cookie.get("token")) {
// ?? ??? ?// ?? ?//用户每次操作,都将cookie设置成2小时
// ?? ??? ?// ?? ?cookie.set("token", cookie.get("token"), 1 / 12)
// ?? ??? ?// ?? ?cookie.set("name", cookie.get("name"), 1 / 12)
// ?? ??? ?// ?? ?config.headers.token = cookie.get("token");
// ?? ??? ?// ?? ?config.headers.name = cookie.get("name");
// ?? ??? ?// }
// ?? ??? ?return config;
// ?? ?},
// ?? ?error => {
// ?? ??? ?return Promise.reject(error.response);
// ?? ?});

// // 路由响应拦截
// // http response 拦截器
// axios.interceptors.response.use(
// ?? ?response => {
// ?? ??? ?if (response.data.resultCode == "404") {
// ?? ??? ??? ?console.log("response.data.resultCode是404")
// ?? ??? ??? ?// 返回 错误代码-1 清除ticket信息并跳转到登录页面
// ?? ??? ??? ?// ? ? ?cookie.del("ticket")
// ?? ??? ??? ?// ? ? ?window.location.href='http://login.com'
// ?? ??? ??? ?return
// ?? ??? ?} else {
// ?? ??? ??? ?return response;
// ?? ??? ?}
// ?? ?},
// ?? ?error => {
// ?? ??? ?return Promise.reject(error.response) // 返回接口返回的错误信息
// ?? ?});
export default axios;

③、将jwt令牌的值放到vuex里面去

通过mutations.js进行值得设置,写setJwt方法;

this关键字只能在vue组件里面出现,在js中要调用vuex的功能window.vm(vm是随便取的名字)代表了this

export default{
? setResturantName:(state,payload)=>{
? ? state.resturantName=payload.resturantName;
? },
? setJwt:(state,payload)=>{
? ? state.
jwt=payload.jwt;
? },

? doAjax:(state,payload)=>{
? ? // 需求:想在当前文件中与后台服务器做数据交互
? ? let _this=payload._this;
? ? let url = _this.axios.urls.SYSTEM_MENU_TREE;
? ? _this.axios.post(url, {}).then((resp) => {
? ? ? console.log(resp);
? ? }).catch(function(error) {
? ? ? console.log(error);
? ? });

? }
}

④、State.js添加jwt变量

export default {
? resturantName: 'XXX餐馆',
? jwt: ''
}

⑤、main.js中给window.vm赋值

⑥、 第二次请求的时候将jwt的值带到请求头里面去

放开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);
});

⑦、Getters.js中定义获取的方法

export default{
? getResturantName:(state)=>{
? ? return state.resturantName;
? },
? getJwt:(state)=>{
? ? return state.
jwt;
? }

}

⑧、界面展示

login.action把jwt在响应头出现,登录请求中没有jwt;

第二次访问首页里面的信息,响应中出现jwt;

第二次请求会把第一次登录后的令牌携带到后端服务器中,作为凭证

问题:

在同一个浏览器中,登录进入首页后,

再次打开一个界面复制首页链接打开首页,访问不到首页,

原因:

第一次请求头中没有jwt,然后请求后台服务器生成了一个jwt返回回来,此时响应头中就要jwt了,

第二次访问请求头中有jwt,是把第一次的响应头拿到的第二次来用,返回回去,请求的时候又带回来了,每一次请求都是上一次的,

当从新开一个界面是,请求头中没有jwt,因此访问不到;

所有说;jwt的安全性比session高,

二、jwt工具类介绍,三种场景

1、jwt工具类

①、jwt令牌包含:

有效载荷:就是用户信息

?签名:就是密码本

有效载荷就是看不懂的字符串,要想看懂有效载荷就得用签名

②、jwtUtils.java

parseJwt方法:解析看不懂的字符串变成看的懂得用户信息;

createJwt方法:把用户信息变成一个看不懂的字符串;

package com.zking.vue.util;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
?* JWT验证过滤器:配置顺序 CorsFilte->JwtUtilsr-->StrutsPrepareAndExecuteFilter
?*
?*/
public class JwtUtils {
?? ?/**
?? ? * JWT_WEB_TTL:WEBAPP应用中token的有效时间,默认30分钟
?? ? */
?? ?public static final long JWT_WEB_TTL = 30 * 60 * 1000;

?? ?/**
?? ? * 将jwt令牌保存到header中的key
?? ? */
?? ?public static final String JWT_HEADER_KEY = "jwt";
?? ?// 指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
?? ?private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;
?? ?private static final String JWT_SECRET = "f356cdce935c42328ad2001d7e9552a3";// JWT密匙
?? ?private static final SecretKey JWT_KEY;// 使用JWT密匙生成的加密key

?? ?static {
?? ??? ?byte[] encodedKey = Base64.decodeBase64(JWT_SECRET);
?? ??? ?JWT_KEY = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
?? ?}
?? ?private JwtUtils() {
?? ?}
?? ?/**
?? ? * 解密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令牌,签发时间为当前时间
?? ? *?
?? ? * @param claims
?? ? * ? ? ? ? ? ?创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
?? ? * @param ttlMillis
?? ? * ? ? ? ? ? ?JWT的有效时间(单位毫秒),当前时间+有效时间=过期时间
?? ? * @return jwt令牌
?? ? */
?? ?public static String createJwt(Map<String, Object> claims, long ttlMillis) {
?? ??? ?// 生成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();
?? ?}
?? ?/**
?? ? * 复制jwt,并重新设置签发时间(为当前时间)和失效时间
?? ? *?
?? ? * @param jwt
?? ? * ? ? ? ? ? ?被复制的jwt令牌
?? ? * @param ttlMillis
?? ? * ? ? ? ? ? ?jwt的有效时间(单位毫秒),当前时间+有效时间=过期时间
?? ? * @return
?? ? */
?? ?public static String copyJwt(String jwt, Long ttlMillis) {
?? ??? ?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();
?? ?}
}

2、三种场景

①、三种场景及结果展示

第一个:是怎么通过jwt工具类去生成jwt令牌和解析jwt令牌;

用户信息都获得了,签发过期时间都出现了,

第二个:jwt令牌过期场景

以下错误就是令牌过期:

第三个:延续令牌的存活时间

令牌过期时间为30分钟,假如一直在使用,30分钟后就要过期(不合理),

因此,需要设置最后使用时间为签发时间,再过30分钟为过期时间

解决方法:copy? jwt令牌,从新设置签发过期时间

②、相关代码

package com.zking.vue.test;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.zking.vue.util.JwtUtils;
import io.jsonwebtoken.Claims;
public class JwtDemo {
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
	@Test
	public void test1() {// 生成JWT
		Map<String, Object> claims = new HashMap<String, Object>();
		claims.put("username", "zss");
		claims.put("age", 18);

		String jwt = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);
		System.out.println(jwt);

		Claims parseJwt = JwtUtils.parseJwt(jwt);
		for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
			System.out.println(entry.getKey() + "=" + entry.getValue());
		}
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("令牌签发时间:" + sdf.format(d1));
		System.out.println("令牌过期时间:" + sdf.format(d2));
	}
	@Test
	public void test2() {// 解析oldJwt
//		String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI5MDMzNjAsImlhdCI6MTU2MjkwMTU2MCwiYWdlIjoxOCwianRpIjoiZDVjMzE4Njg0MDcyNDgyZDg1MDE5ODVmMDY3OGQ4NjkiLCJ1c2VybmFtZSI6InpzcyJ9.XDDDRRq5jYq5EdEBHtPm7GcuBz4S0VhDTS1amRCdf48";
		String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjM1MjU5MjMsImlhdCI6MTU2MzUyNDEyMywiYWdlIjoxOCwianRpIjoiOTAzNmMwY2Q3NGIwNDBjMzgzMDAxYzdiNmZkMzYzZmIiLCJ1c2VybmFtZSI6InpzcyJ9.sgV9fr4fgmmahDFRJnsfazA6R3H-gNMVcg2ucA227n4";
		Claims parseJwt = JwtUtils.parseJwt(oldJwt);
		for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
			System.out.println(entry.getKey() + "=" + entry.getValue());
		}
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("令牌签发时间:" + sdf.format(d1));
		System.out.println("令牌过期时间:" + sdf.format(d2));
	}
	@Test
	public void test3() {// 复制jwt,并延时30秒
		String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI5MDMzNjAsImlhdCI6MTU2MjkwMTU2MCwiYWdlIjoxOCwianRpIjoiZDVjMzE4Njg0MDcyNDgyZDg1MDE5ODVmMDY3OGQ4NjkiLCJ1c2VybmFtZSI6InpzcyJ9.XDDDRRq5jYq5EdEBHtPm7GcuBz4S0VhDTS1amRCdf48";
		String jwt = JwtUtils.copyJwt(oldJwt, JwtUtils.JWT_WEB_TTL);
		Claims parseJwt = JwtUtils.parseJwt(jwt);
		for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
			System.out.println(entry.getKey() + "=" + entry.getValue());
		}
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("令牌签发时间:" + sdf.format(d1));
		System.out.println("令牌过期时间:" + sdf.format(d2));
	}
	@Test
	public void test4() {// 测试JWT的有效时间
		Map<String, Object> claims = new HashMap<String, Object>();
		claims.put("username", "zss");
		String jwt = JwtUtils.createJwt(claims, 3 * 1000L);
		System.out.println(jwt);
		Claims parseJwt = JwtUtils.parseJwt(jwt);
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("令牌签发时间:" + sdf.format(d1));
		System.out.println("令牌过期时间:" + sdf.format(d2));
	}
	@Test
	public void test5() {// 三秒后再解析上面过期时间只有三秒的令牌,因为过期则会报错io.jsonwebtoken.ExpiredJwtException
		String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI4NTMzMzAsImlhdCI6MTU2Mjg1MzMyNywidXNlcm5hbWUiOiJ6c3MifQ.e098Vj9KBlZfC12QSDhI5lUGRLbNwb27lrYYSL6JwrQ";
		Claims parseJwt = JwtUtils.parseJwt(oldJwt);
		// 过期后解析就报错了,下面代码根本不会执行
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("令牌签发时间:" + sdf.format(d1));
		System.out.println("令牌过期时间:" + sdf.format(d2));
	}
}

三、jwt与vuex配合在SPA项目中的应用

jwt与vuex的整合中讲过

结束!!!

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-11-18 11:30:16  更:2021-11-18 11:31:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:35:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码