赞
踩
说明:
这是基于青戈的token配置写的
因为青戈的代码有些问题,所以我写了一篇博客方便我以后自己配置token
原文链接:
青戈:SpringBoot集成JWT(极简版)
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
package com.example.springboot.common; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired JwtInterceptor jwtInterceptor; @Override public void configurePathMatch(PathMatchConfigurer configurer) { // 指定controller统一的接口前缀 configurer.addPathPrefix("/api", clazz -> clazz.isAnnotationPresent(RestController.class)); } // 加自定义拦截器JwtInterceptor,设置拦截规则 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**") .excludePathPatterns("/api/user/login", "/api/user/register"); } }
注意: tomcat10已把javax换成了jakarta,如果你用springboot3.0.x及以上的版本,那请把所有javax开头的头文件都改成jakarta开头
这里青戈有一处错误,在getCurrentUser方法里,具体看下面代码
package com.example.springboot.utils; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.example.springboot.common.JwtInterceptor; import com.example.springboot.entity.po.User; import com.example.springboot.service.IUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import java.util.Date; @Component @Slf4j public class TokenUtils { private static IUserService staticUserService; @Resource private IUserService userService; @PostConstruct public void setUserService() { staticUserService = userService; } /** * 生成token * * @return */ public static String getToken(String userId, String sign) { return JWT.create().withAudience(userId) // 将 user id 保存到 token 里面,作为载荷 .withExpiresAt(DateUtil.offsetHour(new Date(), 2)) // 2小时后token过期 .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥 } /** * 获取当前登录的用户信息 * * @return user对象 * /admin?token=xxxx */ public static User getCurrentUser() { String token = null; try { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); token = request.getHeader("token"); if (StrUtil.isBlank(token)) { // 这里青戈写错了,应该是isBlank token = request.getParameter("token"); } if (StrUtil.isBlank(token)) { log.error("获取当前登录的token失败, token: {}", token); return null; } String userId = String.valueOf(JWT.decode(token).getAudience().get(0)); return staticUserService.getUserById(Integer.valueOf(userId)); } catch (Exception e) { log.error("获取当前登录的管理员信息失败, token={}", token, e); return null; } } }
package com.example.springboot.common; import cn.hutool.core.util.StrUtil; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTVerificationException; import com.example.springboot.entity.po.User; import com.example.springboot.exception.ServiceException; import com.example.springboot.service.IUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @Component @Slf4j public class JwtInterceptor implements HandlerInterceptor { private static final String ERROR_CODE_401 = "401"; @Autowired private IUserService userService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("token"); if (StrUtil.isBlank(token)) { token = request.getParameter("token"); } // 执行认证 if (StrUtil.isBlank(token)) { throw new ServiceException(ERROR_CODE_401, "无token,请重新登录"); } // 获取 token 中的userId String userId; User user; try { userId = JWT.decode(token).getAudience().get(0); // 根据token中的userid查询数据库 user = userService.getUserById(Integer.parseInt(userId)); } catch (Exception e) { String errMsg = "token验证失败,请重新登录"; log.error(errMsg + ", token=" + token, e); throw new ServiceException(ERROR_CODE_401, errMsg); } if (user == null) { throw new ServiceException(ERROR_CODE_401, "用户不存在,请重新登录"); } try { // 用户密码加签验证 token, 对应TokenUtlis,java中的.sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥 JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build(); jwtVerifier.verify(token); // 验证token } catch (JWTVerificationException e) { throw new ServiceException(ERROR_CODE_401, "token验证失败,请重新登录"); } return true; } }
package com.example.springboot.common; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired JwtInterceptor jwtInterceptor; @Override public void configurePathMatch(PathMatchConfigurer configurer) { // 指定controller统一的接口前缀 configurer.addPathPrefix("/api", clazz -> clazz.isAnnotationPresent(RestController.class)); } // 加自定义拦截器JwtInterceptor,设置拦截规则 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor).addPathPatterns("/api/**") .excludePathPatterns("/api/user/login", "/api/user/register"); } }
package com.example.springboot.common; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址 corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头 corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法 source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置 return new CorsFilter(source); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。