引入依赖
<!-- JWT依赖 --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- JWT相关依赖,jdk1.8以上版本还需引入以下依赖 --><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>3.0.2</version></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-core</artifactId><version>3.0.2</version></dependency><dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version></dependency>
示例
复制下拉即可测试使用了
package xx.convert.util;import io.jsonwebtoken.*;import java.util.Date;
import java.util.UUID;/*** Jwt-token工具类* @author yyq*/
public class JwtUtil {private static long expire_time = 2000 ; // 2秒是做测试用的(设置一个钟 1000 * 60 * 60 * 1)private static String sign = "AsldjlJDLKKJSDKLFJlksjlkjlkSDL"; // 加密签名密钥/*** 创建token返回* @return*/public static String createToken() {// 创建一个JwtBuilder对象JwtBuilder jwtBuilder = Jwts.builder();// jwtToken -> abc.def.xyzString jwtToken = jwtBuilder// Header:头部.setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")// PayLoad:载荷(用户信息,就是需要保存的数据).claim("userId", "101").claim("userName", "zhangsan").claim("roleName", "admin").setSubject("user-info") // 这个载荷的名称// Token的过期时间.setExpiration(new Date(System.currentTimeMillis() + expire_time)) // 从当前系统时间往后存活一小时// id字段.setId(UUID.randomUUID().toString())// 设置加密算法和签名.signWith(SignatureAlgorithm.HS256, sign)// 使用”."连接成一个完整的字符串.compact();return jwtToken;}/*** 获取解析的用户信息* @param token* @return Claims*/public static Claims parserJwt(String token){if (token == null || token.trim().length() == 0){return null;}Jws<Claims> jws = Jwts.parser().setSigningKey(sign).parseClaimsJws(token);return jws.getBody(); // 存储的用户信息}/*** 获取解析的用户ID* @param token* @return*/public static String parserJwtById(String token){if (token == null || token.trim().length() == 0){return "";}Jws<Claims> jws = Jwts.parser().setSigningKey(sign).parseClaimsJws(token);return (String)jws.getBody().get("userId"); // 存储的用户信息}/*** 校验token* @param token* @return*/public static boolean checkToken(String token){if (token == null || token.trim().length() == 0){return false;}try{Jwts.parser().setSigningKey(sign).parseClaimsJws(token);}catch (Exception e){e.printStackTrace();return false;}return true;}/*** 开始测试* @param args* @throws InterruptedException*/public static void main(String[] args) throws InterruptedException {System.out.println("------------------------------【创建token】---------------------------");String token = JwtUtil.createToken();System.out.println(token);System.out.println("------------------------------【第一次解析】---------------------------");boolean b = JwtUtil.checkToken(token);System.out.println(b);if(b){Claims claims = parserJwt(token);System.out.println(claims.getExpiration());System.out.println(claims.getSubject());System.out.println(claims.get("userId"));System.out.println(claims.get("userName"));System.out.println(claims.get("roleName"));}else {System.out.println("========token失效=========");}System.out.println("------------------------------【延迟3秒】---------------------------");Thread.sleep(3000);System.out.println("------------------------------【第二次解析】---------------------------");b = JwtUtil.checkToken(token);System.out.println(b);if(b){Claims claims = parserJwt(token);System.out.println(claims.getExpiration());System.out.println(claims.getSubject());System.out.println(claims.get("userId"));System.out.println(claims.get("userName"));System.out.println(claims.get("roleName"));}else {System.out.println("========token失效=========");}}}
实际项目使用
拦截器
关键preHandle方法,其他附带的
package xx.convert.util;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 拦截器* @author yyq*/
@Component
public class MyInterceptor implements HandlerInterceptor {/*** 执行前* @param arg0* @param arg1* @param arg2* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {// 请求路径,如需指定,则判断校验String url = arg0.getRequestURI();if(url.indexOf("views") != -1){String token = arg0.getHeader("token");boolean b = JwtUtil.checkToken(token);if(!b){return false;}else {String userId = JwtUtil.parserJwtById(token);arg0.setAttribute("userId", userId);}}return true;}/*** 执行后* @param arg0* @param arg1* @param arg2* @param arg3* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)throws Exception {// TODO Auto-generated method stub}/*** 页面渲染* @param arg0* @param arg1* @param arg2* @param arg3* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)throws Exception {// TODO Auto-generated method stub}}
跨越问题解决
关键addCorsMappings方法,其他附带的
package xx.convert.util;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 视图处理器** @author yyq*/
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {@Value("${file.upload.path}")private String uploadFolder = "D://nginx//projectName//";@Autowiredprivate MyInterceptor myInterceptor;/*** 跨越问题解决* @param registry*/@Overridepublic void addCorsMappings(CorsRegistry registry) {// 为url添加映射路径(配置域名下的资源)registry.addMapping("/**")// 配置允许访问的源,*表示允许全部域名。(小于springboot 2.4版本).allowedOrigins("*")// 如果版本高于springboot 2.4,则使用//.allowedOriginPatterns("*")// 设置允许的请求方式.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")// 设置允许的header.allowedHeaders("*")// 设置是否允许发送Cookie,用于凭证请求,默认不发送cookie。.allowCredentials(true)// 设置预检请求的有效时间.maxAge(3600);}/*** 静态文件路径设置** @param registry*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// String path1 = ResourceUtils.getURL("classpath:").getPath();// String path2 = ClassUtils.getDefaultClassLoader().getResource("").getPath();registry.addResourceHandler("/**").addResourceLocations("classpath:/static/", "file:" + uploadFolder);// 上传的图片代理文件夹路径registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");}/*** 拦截器配置** @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns("/**");//所有请求都被拦截,包括静态资源/*registry.addInterceptor(new InterceptorConfig()).addPathPatterns("/**")//所有请求都被拦截,包括静态资源.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");//放行的请求*/}}