jwt详细介绍

jwt详细介绍

  • 1.jwt 简介:
  • 2.jwt 工具类介绍
  • 3.案列演示:
    • 3.1并在web.xml进行配置过滤器
  • 3.2过滤
  • 3.3全局响应设置

1.jwt 简介:

。JWT(JSON Web Token)
是一种用于安全传输信息的开放标准(RFC 7519)。它由三部分组成:头部(header)、负载(payload)和签名(signature)。

头部包含了关于该JWT的元数据,如使用的加密算法类型等。负载存储了需要传输的数据,比如用户的身份信息、权限等。签名是由头部、负载和一个密钥生成的,用于验证JWT是否被篡改。

JWT的工作流程如下:

用户登录时,服务器验证用户的身份,并生成一个JWT。
服务器将JWT发送给客户端,并保存在客户端的存储介质中(通常是浏览器的Cookie或本地存储)。
客户端在后续的请求中将JWT通过HTTP头部或请求参数的方式发送给服务器。
服务器接收到JWT后,会对其进行验证,包括验证签名的有效性、判断JWT是否过期等。
如果JWT验证通过,服务器可以使用其中的数据来完成相应的操作,比如认证用户身份、授权等。
JWT的优点包括:

简洁:JWT使用JSON格式存储数据,使得它更易读、编写和解析。
自包含:JWT中包含了所有必要的信息,减少了服务器查询数据库的次数。
可扩展:JWT的负载部分可以自定义,可以根据需要添加额外的字段。
安全性:通过使用签名和密钥,JWT可以验证数据的完整性和源信任。
然而,需要注意的是,由于JWT是基于客户端存储的,因此在使用时需要考虑到安全性问题,比如防止JWT被篡改、泄露等。

2.jwt 工具类介绍

package com.zking.ssm.jwt;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那部分,jwt已经将这部分内容封装好了。private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;private static final String JWT_SECRET = "f356cdce935c42328ad2001d7e9552a3";// JWT密匙private static final SecretKey JWT_KEY;// 使用JWT密匙生成的加密keystatic {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的时间,即签发时间 2021-10-30 10:02:00 -> 30 10:32:00long nowMillis = System.currentTimeMillis();//链式语法:// 下面就是在为payload添加各种标准声明和私有声明了// 这里其实就是new一个JwtBuilder,设置jwt的bodyJwtBuilder 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) {//解密JWT,获取所有的声明(私有和标准)//oldClaims claims = parseJwt(jwt);// 生成JWT的时间,即签发时间long nowMillis = System.currentTimeMillis();// 下面就是在为payload添加各种标准声明和私有声明了// 这里其实就是new一个JwtBuilder,设置jwt的bodyJwtBuilder 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(JSON Web Token)的工具类。JWT是一种用于安全传输信息的开放标准,通过使用签名和密钥来验证数据的完整性和源信任。

该工具类包括以下功能:

解密JWT:根据传入的JWT字符串,使用密钥对其进行解密,获取其中的所有声明(包括标准和私有声明)。

创建JWT令牌:根据传入的私有声明、有效时间等参数,生成一个新的JWT令牌,并返回该令牌。

复制JWT:根据传入的JWT字符串和有效时间,复制并重新设置JWT的签发时间和失效时间,并返回新的JWT字符串。

在构建JWT时,该工具类使用了Apache Commons Codec库中的Base64类进行编码和解码操作。另外,使用了io.jsonwebtoken库提供的JwtBuilder和Jwts类进行JWT的创建和解析操作。

需要注意的是,JWT_SECRET是一个密钥字符串,用于生成加密key,并且应当保持安全;JWT_WEB_TTL是JWT的有效时间,默认为30分钟;JWT_HEADER_KEY是将JWT令牌保存到HTTP头部中的键名。

此外,在使用该工具类时,需要按照一定的顺序配置过滤器,以确保JWT验证的正确进行。

总体而言,这个工具类提供了便捷的方法来生成和解析JWT令牌,方便在WEB应用中进行身份验证和授权操作。
工具类测试

package com.zking.ssm.service.impl;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;import com.zking.ssm.jwt.JwtUtils;
import io.jsonwebtoken.Claims;
import org.junit.*;public class JwtDemo {private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");@Testpublic void test1() {// 生成JWT//JWT Token=Header.Payload.Signature//头部.载荷.签名//Payload=标准声明+私有声明+公有声明//定义私有声明Map<String, Object> claims = new HashMap<String, Object>();claims.put("username", "zss");claims.put("age", 18);//TTL:Time To LiveString jwt = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);System.out.println(jwt);//获取Payload(包含标准和私有声明)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));}@Testpublic void test2() {// 解析oldJwt//io.jsonwebtoken.ExpiredJwtException:JWT过期异常//io.jsonwebtoken.SignatureException:签名异常//String oldJwt="eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1OTA3MTg2NzcsImlhdCI6MTU5MDcxNjg3NywiYWdlIjoxOCwianRpIjoiNDFmZjFiZGFkYzkxNDA3OGE4ZGUyNGRkZDEwYjU4N2IiLCJ1c2VybmFtZSI6InpzcyJ9.DdPvioX6kuhV6lEfD9QAN2eQSk_mO3dYkmDmTQsqa78";//eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzU1NjE3MjcsImlhdCI6MTYzNTU1OTkyNywiYWdlIjoxOCwianRpIjoiN2RlYmIzM2JiZTg3NDBmODgzNDI5Njk0ZWE4NzcyMTgiLCJ1c2VybmFtZSI6InpzcyJ9.dUR-9JUlyRdoYx-506SxXQ3gbHFCv0g5Zm8ZGzK1fzwString newJwt="eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ6a2luZyIsImV4cCI6MTY5NzIxMTkxNywiaWF0IjoxNjk3MjEwMTE3LCJhZ2UiOjE4LCJqdGkiOiJlMmM1MDViYTcyMDA0NjZjOGVjNzExMTc4NjBiM2QzYiIsInVzZXJuYW1lIjoienNzIn0.FUWLkxJD64JyT_PepC2sxlOc1TFHBOQc_Fx3xHoDn2Y";String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzU1NjE3MjcsImlhdCI6MTYzNTU1OTkyNywiYWdlIjoxOCwianRpIjoiN2RlYmIzM2JiZTg3NDBmODgzNDI5Njk0ZWE4NzcyMTgiLCJ1c2VybmFtZSI6InpzcyJ9.dUR-9JUlyRdoYx-506SxXQ3gbHFCv0g5Zm8ZGzK1fzw";Claims parseJwt = JwtUtils.parseJwt(newJwt);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));}@Testpublic void test3() {// 复制jwt,并延时30分钟String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ6a2luZyIsImV4cCI6MTY5NzIxMTkxNywiaWF0IjoxNjk3MjEwMTE3LCJhZ2UiOjE4LCJqdGkiOiJlMmM1MDViYTcyMDA0NjZjOGVjNzExMTc4NjBiM2QzYiIsInVzZXJuYW1lIjoienNzIn0.FUWLkxJD64JyT_PepC2sxlOc1TFHBOQc_Fx3xHoDn2Y";//String newJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDU3NTM2NTUsImlhdCI6MTYwNTc1MTg1NSwiYWdlIjoxOCwianRpIjoiYmNmN2Q1MzQ2YjE3NGU2MDk1MmIxYzQ3ZTlmMzQyZjgiLCJ1c2VybmFtZSI6InpzcyJ9.m1Qn84RxgbKCnsvrdbbAnj8l_5Jwovry8En0j4kCxhc";//String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI5MDMzNjAsImlhdCI6MTU2MjkwMTU2MCwiYWdlIjoxOCwianRpIjoiZDVjMzE4Njg0MDcyNDgyZDg1MDE5ODVmMDY3OGQ4NjkiLCJ1c2VybmFtZSI6InpzcyJ9.XDDDRRq5jYq5EdEBHtPm7GcuBz4S0VhDTS1amRCdf48";String newJwt = JwtUtils.copyJwt(oldJwt, JwtUtils.JWT_WEB_TTL);System.out.println(newJwt);Claims parseJwt = JwtUtils.parseJwt(newJwt);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));}@Testpublic 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));}@Testpublic void test5() {// 三秒后再解析上面过期时间只有三秒的令牌,因为过期则会报错io.jsonwebtoken.ExpiredJwtException//String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MzU1NjMzODIsImlhdCI6MTYzNTU2MTU4MiwiYWdlIjoxOCwianRpIjoiN2RlYmIzM2JiZTg3NDBmODgzNDI5Njk0ZWE4NzcyMTgiLCJ1c2VybmFtZSI6InpzcyJ1.F4pZFCjWP6wlq8v_udfhOkNCpErF5QlL7DXJdzXTHqE";String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ6a2luZyIsImV4cCI6MTY2MjM0Njg3MSwiaWF0IjoxNjYyMzQ1MDcxLCJhZ2UiOjE4LCJqdGkiOiI4YjllNzc3YzFlMDM0MjViYThmMDVjNTFlMTU3NDQ1MiIsInVzZXJuYW1lIjoienNzIn9.UWpJxPxwJ09PKxE2SY5ME41W1Kv3jP5bZGKK-oNUDuM";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的生成、解析和复制功能。

test1() 方法:生成JWT

首先定义了一个包含私有声明的 Map 对象,其中包括了用户的用户名和年龄信息。
然后调用 JwtUtils.createJwt() 方法生成JWT令牌,并将令牌打印输出。
接着使用 JwtUtils.parseJwt() 方法解析JWT,获取其中的声明信息并打印出来,包括标准声明和私有声明。
最后打印出令牌的签发时间和过期时间。
在这里插入图片描述

test2() 方法:解析JWT

将一个已经生成的 JWT 令牌传入 JwtUtils.parseJwt() 方法进行解析。
使用循环遍历的方式打印出解析后的所有声明信息,包括标准声明和私有声明。
打印出令牌的签发时间和过期时间。
在这里插入图片描述
test3() 方法:复制JWT并延时30分钟
将一个已经生成的 JWT 令牌传入 JwtUtils.copyJwt() 方法进行复制,同时指定新的有效时间(延时30分钟)。
返回复制后的新的 JWT 令牌并打印出来。
使用 JwtUtils.parseJwt() 方法解析新的 JWT 令牌,打印出所有声明信息,并打印出令牌的签发时间和过期时间。
在这里插入图片描述

test4() 方法:测试JWT的有效时间

定义一个只包含用户名信息的私有声明。
调用 JwtUtils.createJwt() 方法生成 JWT 令牌,并指定有效时间为3秒。
打印出生成的 JWT 令牌。
使用 JwtUtils.parseJwt() 方法解析 JWT 令牌,打印出令牌的签发时间和过期时间。
在这里插入图片描述

test5() 方法:测试JWT过期

将一个已经过期的 JWT 令牌传入 JwtUtils.parseJwt() 方法进行解析。
由于令牌已经过期,解析时会抛出 io.jsonwebtoken.ExpiredJwtException 异常,不会执行后续代码
在这里插入图片描述
工具类测试结果。

3.案列演示:

1.前面提到过JWT跨语言那就涉及到跨域问题,首先在我们的过滤器里面加入允许JWT的跨域请求

package com.zking.ssm.util;import java.io.IOException;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;/*** 配置tomcat允许跨域访问* * @author Administrator**/
public class CorsFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;HttpServletRequest req = (HttpServletRequest) servletRequest;// Access-Control-Allow-Origin就是我们需要设置的域名// Access-Control-Allow-Headers跨域允许包含的头。// Access-Control-Allow-Methods是允许的请求方式httpResponse.setHeader("Access-Control-Allow-Origin", "*");// *,任何域名httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");//允许客户端发一个新的请求头jwthttpResponse.setHeader("Access-Control-Allow-Headers","responseType,Origin,X-Requested-With, Content-Type, Accept, jwt");//允许客户端处理一个新的响应头jwthttpResponse.setHeader("Access-Control-Expose-Headers", "jwt,Content-Disposition");//httpResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");//httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");// axios的ajax会发两次请求,第一次提交方式为:option,直接返回即可if ("OPTIONS".equals(req.getMethod())) {return;}filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
}

3.1并在web.xml进行配置过滤器

<!--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>

3.2过滤

package com.zking.ssm.jwt;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;/*** * JWT验证过滤器,配置顺序 :CorsFilter-->JwtFilter-->struts2中央控制器* * @author Administrator**/public class JwtFilter implements Filter {// 排除的URL,一般为登陆的URL(请改成自己登陆的URL)private static String EXCLUDE = "^/user/userLogin?.*$";private static Pattern PATTERN = Pattern.compile(EXCLUDE);private boolean OFF = false;// true关闭jwt令牌验证功能@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;//获取当前请求路径。只有登录的请求路径不进行校验之外,其他的URL请求路径必须进行JWT令牌校验//http://localhost:8080/ssh2/bookAction_queryBookPager.action//req.getServletPath()==/bookAction_queryBookPager.actionString path = req.getServletPath();if (OFF || isExcludeUrl(path)) {// 登陆直接放行chain.doFilter(request, response);return;}// 从客户端请求头中获得令牌并验证//token=头.载荷.签名String jwt = req.getHeader(JwtUtils.JWT_HEADER_KEY);Claims claims = this.validateJwtToken(jwt);//在这里请各位大哥大姐从JWT令牌中提取payload中的声明部分//从声明部分中获取私有声明//获取私有声明中的User对象 -> ModulesBoolean flag=false;if (null == claims) {// resp.setCharacterEncoding("UTF-8");resp.sendError(403, "JWT令牌已过期或已失效");return;} else {//1.获取已经解析后的payload(私有声明)//2.从私有声明中当前用户所对应的权限集合List<String>或者List<Module>//3.循环权限(Module[id,url])// OK,放行请求 chain.doFilter(request, response);// NO,发送错误信息的JSON// ObjectMapper mapper=new ObjectMapper()// mapper.writeValue(response.getOutputStream(),json)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) {//该解析方法会验证:1)是否过期 2)签名是否成功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);// }}

state

export default{eduName:'猪猪教育',jwt:''
}

getters

export default{geteduName:(state)=>{return state.eduName;},getjwt:(state)=>{return state.jwt;}
}

mutation

export default{setName:(state,payload)=>{state.eduName=payload.eduName;},setJwt:(state,payload)=>{state.jwt=payload.jwt;}
}

3.3全局响应设置

/*** 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){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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/157921.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ue5打包失败与优化项目

打包报错&#xff1a; PackagingResults: Error: Multiple game targets found for project. Specify the desired target using the -Target... argument. 解决方案&#xff1a; 关闭项目后&#xff0c;删除项目目录下的 Intermediate 文件 再重新启动项目打包即可 参考&…

Linux实现原理 — I/O 处理流程与优化手段

Linux I/O 接口 Linux I/O 接口可以分为以下几种类型&#xff1a; 文件 I/O 接口&#xff1a;用于对文件进行读写操作的接口&#xff0c;包括 open()、read()、write()、close()、lseek() 等。 网络 I/O 接口&#xff1a;用于网络通信的接口&#xff0c;包括 socket()、conne…

buuctf week2-web-ez_sql

闭合之后尝试判断字段数&#xff0c;存在WAF&#xff0c;使用大小写绕过&#xff08;后面的sql语句也需要进行大小写绕过&#xff09; ?id1 Order by 5-- 测出有5列 ?id1 Order by 6-- 查一下数据库名、版本、用户等信息 ?id1Union Select database(),version(),user(),4,…

关于Vue+webpack使用unocss编写CSS,打包后CSS没加前缀

关于Vuewebpack使用unocss编写CSS&#xff0c;打包后CSS没加前缀&#xff0c;封装了一个插件去解决了这个问题 unocss-postcss-webpack-plugin unocss在vite中使用配置&#xff0c;关于unocss在vite中使用&#xff0c;自行查阅官网 https://unocss.dev/integrations/vite ,vi…

最详细STM32,cubeMX 点亮 led

这篇文章将详细介绍 如何在 stm32103 板子上点亮一个LED. 文章目录 前言一、开发环境搭建。二、LED 原理图解读三、什么是 GPIO四、cubeMX 配置工程五、解读 cubeMX 生成的代码六、延时函数七、控制引脚状态函数点亮 LED 八、GPIO 的工作模式九、为什么使用推挽输出驱动 LED总结…

鲲山科技:引入和鲸 ModelWhale,实现量化策略的高效迭代

量化投资是数据科学在金融行业的应用。 2023 年&#xff0c;量化行业的超额收益开始收敛&#xff0c;量化私募如何形成自身核心竞争力&#xff1f; 和鲸拜访客户鲲山科技&#xff08;深圳&#xff09;&#xff0c;揭示其“弯道超车”的独家秘诀。 群体作战 年初至今&#xff…

idea中导入eclipse的javaweb项目——tomact服务(保姆级别)

idea中导入eclipse的javaweb项目——tomact服务&#xff08;保姆级别&#xff09; 1. 导入项目2. Project Settings下的各种配置步骤2.1 检查/修改 jdk 的引入2.2 配置Modules-Dependencies2.2.1 删掉eclipse相关的多余配置2.2.2 删掉jar包2.2.3 添加tomcat的依赖 2.3 配置Libr…

JMeter定时器

一. 同步定时器&#xff08;Synchronizing Timer) &#xff08;在Loadrunner中叫做集合点&#xff09; 思考&#xff1a; 如何模拟多个用户同时抢一个红包&#xff1f;如何测试电商网站中抢购活动、秒杀活动&#xff1f; 1.1 介绍 Sync Timer的目的是阻塞线程&#xff0c;直…

云原生SIEM解决方案

云原生&#xff08;Cloud Native&#xff09;是一种基于云计算的软件开发和部署方法论&#xff0c;它强调将应用程序和服务设计为云环境下的原生应用&#xff0c;以实现高可用性、可扩展性和灵活性。 云原生的优势有哪些 高可用性&#xff1a;云原生可以实现应用程序的高可用…

分享一下便利店怎么做微信小程序

便利店微信小程序开发&#xff0c;让生意更便捷&#xff01; 在这个数字化时代&#xff0c;微信小程序已经成为一种新的生活方式。它不仅改变了人们的消费习惯&#xff0c;还为各行各业提供了无限商机。对于便利店来说&#xff0c;微信小程序是一个绝佳的营销工具&#xff0c;…

汉诺塔问题

汉诺塔问题 本文部分截图来源&#xff1a;汉诺塔可视化小游戏 移动最终目标&#xff1a;将A柱中的所有盘移动至C柱 移动过程要求&#xff1a;1.每次只能移动一个盘 2.每次移动后必须保证小盘在大盘上方 问题简化 我们先将三个盘&#xff08;n-1&#xff0c;n4&#xff09;看作…

微信小程序clearInterval无法关闭时间间隔器问题解决

今天在微信小程序遇到了一个问题 我的代码是这样的 // 关闭动画函数 AnimationOff() {//定义时间间隔器clearInterval(this.animationTimer) }, DefineAnimation() {//定义时间间隔器this.animationTimer setInterval(() > {console.log("执行");}, 1000) },但是…

C++ - git 命令行

为什么要有 git 你很可能遇到过这种情况&#xff0c;在写项目的时候&#xff0c;要我不符合 leader 的要求&#xff0c;因而修改了很多个版本&#xff0c;但是修改到最后一版的时候&#xff0c;leader 有觉得当前这版还没有之前 某一版好&#xff0c;现在又要求你在 之前的那一…

MyBatis基础之自动映射、映射类型、文件注解双配置

文章目录 自动映射原理jdbcType同时启用配置文件和注解两种配置方式 自动映射原理 在 MyBatis 的配置文件&#xff08;settings 元素部分&#xff09;中&#xff0c;有一个 autoMappingBehavior 配置&#xff0c;其默认值为 PARTIAL &#xff0c;表示 MyBatis 会自动映射&…

Spring实战 | Spring AOP核心秘笈之葵花宝典

Spring实战系列文章&#xff1a; Spring实战 | Spring IOC不能说的秘密&#xff1f; 国庆中秋特辑系列文章&#xff1a; 国庆中秋特辑&#xff08;八&#xff09;Spring Boot项目如何使用JPA 国庆中秋特辑&#xff08;七&#xff09;Java软件工程师常见20道编程面试题 国庆…

SpringBoot日志文件

目录 日志级别 设置日志级别 日志持久化 获取日志的两种方式 1.LoggerFactory.getLogger(类名.class) 2. lombok的slf4j注解和log对象 日志级别 由低到高依次是&#xff1a;trace->debug->info->warn->error->fatal 其中当程序里设置了日志级别后&#xff0c;程…

实验3:左右循环LED灯

获取流水灯工程&#xff1a; 方式一&#xff1a; keilproteus 完成最小系统&#xff0c;点亮led 灯实验_吴小凹的博客-CSDN博客 方式二&#xff1a; Flowing_led.zip - 蓝奏云直接下载。 原理图修改&#xff1a; 无须修改只需要使用流水灯的工程即可&#xff0c;解压到桌面…

记一次Hbase2.1.x历史数据数据迁移方案

查看待迁移的表 list_namespace_tables vaas_dwm2. 制作待迁移表“DWM_TRIP_PART”的快照 snapshot vaas_dwm:DWM_TRIP_PART,dwm_trip_part_snapshot3. 统计待迁移表数据总数 hbase org.apache.hadoop.hbase.mapreduce.RowCounter vaas_dwm:DWM_TRIP_PART

人脸活体检测技术的应用,有效避免人脸识别容易被攻击的缺陷

随着软件算法和物理终端的进步&#xff0c;人脸识别现在越来越被广泛运用到生活的方方面面&#xff0c;已经成为了重要的身份验证手段&#xff0c;但同时也存在着自身的缺陷&#xff0c;目前常规人脸识别技术可以精准识别目标人像特征&#xff0c;并迅速返回比对结果&#xff0…

ADAS可视化系统,让自动驾驶更简单 -- 入门篇

随着车载芯片的升级、技术的更新迭代&#xff0c;可视化ADAS逐渐变成汽车的标配走入大家的生活中&#xff0c;为大家的驾车出行带来切实的便捷。那么你了解HMI端ADAS的实现过程吗&#xff1f;作为ADAS可视化系统的入门篇&#xff0c;就跟大家聊一聊目前较常见的低消耗的一种ADA…