首页IT科技springboot集成jwt登陆认证,设置跳过认证(在 SpringBoot 项目中简单实现 JWT 验证)

springboot集成jwt登陆认证,设置跳过认证(在 SpringBoot 项目中简单实现 JWT 验证)

时间2025-06-20 15:13:28分类IT科技浏览3922
导读:使用 SpringBoot 提供 api 的时候,我更喜欢使用 jwt 的方式来做验证。网上有会多 Spring Security 整合 jwt 的,也有 Shiro 整合 jwt 的,感觉有点复杂。这里分享一下自己在项目中的简单实现。...

使用 SpringBoot 提供 api 的时候            ,我更喜欢使用 jwt 的方式来做验证             。网上有会多 Spring Security 整合 jwt 的                   ,也有 Shiro 整合 jwt 的      ,感觉有点复杂                  。这里分享一下自己在项目中的简单实现      。

依赖包

除了 SpringBoot 基本的依赖      ,需要一个生成 jwt 和序列化的包             。生成 jwt 的包依赖很多                   ,因为我项目里使用了 hutool 这个包            ,就只用用它了                  。

<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.9</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.9</version> </dependency>

jwt用户模型

定义一个 Jwt 的 sub 字段模型      ,存储用户:

import lombok.Data; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; @Data public class JwtUser { /** * 用户编号 */ private Integer id; /** * 用户名 */ private String name; /** * 角色 */ private String role; /** * 获取当前请求用户 * @return */ public static JwtUser getCurrentUser() { RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); return (JwtUser) request.getAttribute("user"); } }

验证注解

定义一个用于请求类和方法的注解

import java.lang.annotation.*; @Inherited @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Authorize { /** * 是否匿名可以访问 * @return */ boolean anonymous() default false; /** * 角色 * @return */ String[] roles() default {}; }

JWT 帮助类

用于生成 jwt 和 解析 JwtUser 对象      。

import cn.hutool.jwt.JWT; import cn.hutool.jwt.JWTUtil; import cn.hutool.jwt.signers.JWTSigner; import cn.hutool.jwt.signers.JWTSignerUtil; import com.google.gson.Gson; import com.mpyf.xapi.security.JwtUser; import lombok.var; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; public class JwtTokenUtils { public static final String SECRET = "your_secret"; public static final String ISS = "com.your.cn"; private static final int EXPIRATIONHOURS = 24; //过期时间24小时 //创建token public static String createToken(JwtUser user) { return createToken(user, EXPIRATIONHOURS); } public static String createToken(JwtUser user, int hours) { String subJson = new Gson().toJson(user); JWTSigner jwtSigner = JWTSignerUtil.hs512(SECRET.getBytes()); JWT jwt = JWT.create().setSigner(jwtSigner); jwt .setJWTId(UUID.randomUUID().toString().replace("-", "")) .setSubject(subJson) //用户信息 .setIssuer(ISS) //签发者 //.setAudience("受众") //.setNotBefore(new Date()) .setIssuedAt(new Date()) .setExpiresAt(new Date(System.currentTimeMillis() + hours * 3600 * 1000)); return jwt.sign(); } public static JwtUser getUser(String token) { if (StringHelper.isNullOrEmpty(token)) return null; var jwt = JWTUtil.parseToken(token); JWTSigner jwtSigner = JWTSignerUtil.hs512(SECRET.getBytes()); jwt.setSigner(jwtSigner); if (jwt.validate(10)) { var subJson = jwt.getPayload("sub").toString(); JwtUser user = new Gson().fromJson(subJson, JwtUser.class); return user; } else { return null; } } }

验证拦截器

定义jwt的验证拦截器                   ,从请求头获取 token 解析并验证       。

import com.mpyf.xapi.helper.JwtTokenUtils; import com.mpyf.xapi.helper.StringHelper; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; /** * jwt 验证拦截器 */ @Component public class JwtAuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //Authorization:Bearer+空格+token String token = request.getHeader("Authorization"); if (token != null) { token = token.replace("Bearer ", ""); } //处理模拟登录的jwt if (StringHelper.isNullOrEmpty(token)) { token = request.getParameter("jwt"); } if (StringHelper.isNullOrEmpty(token)) { //兼容从请求参数传token Object jwt = request.getAttribute("jwt"); if (jwt != null) { token = jwt.toString(); } } JwtUser user = JwtTokenUtils.getUser(token); request.setAttribute("user", user); if (handler instanceof HandlerMethod) { HandlerMethod h = (HandlerMethod) handler; Authorize authorize = h.getMethodAnnotation(Authorize.class); if (authorize == null) { authorize = h.getMethod().getDeclaringClass().getAnnotation(Authorize.class); } //如果没有Authorize或者可以匿名访问            ,直接返回 if (authorize != null && !authorize.anonymous()) { { if (user == null) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return false; } else if (authorize.roles() != null && authorize.roles().length > 0 && Arrays.stream(authorize.roles()).allMatch(s -> !s.equalsIgnoreCase(user.getRole()))) { //没权限 response.sendError(HttpServletResponse.SC_FORBIDDEN); return false; } } } } return true; } }

注册拦截器

在 WebMvc 配置中注册拦截器,并支持跨域请求

import com.mpyf.xapi.security.JwtAuthInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.*; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired JwtAuthInterceptor jwtAuthInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtAuthInterceptor).addPathPatterns("/api/**"); WebMvcConfigurer.super.addInterceptors(registry); } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOriginPatterns("*") .allowedMethods("*") .allowedHeaders("*") //.maxAge(3600) .allowCredentials(true); WebMvcConfigurer.super.addCorsMappings(registry); } }

Controller中使用

@RestController @RequestMapping("/api/test") @Authorize(roles = {"admin", "user"}) public class TestController { @GetMapping("admin_and_user") public String admin_and_user(){ return "admin 和 user 角色都可以访问"; } @GetMapping("admin_only") @Authorize(roles = "admin") //覆盖Controller的设置 public String admin_only(){ return "只有 admin 角色可以访问"; } @GetMapping("public_all") @Authorize(anonymous = true) public String public_all(){ return "匿名可以访问"; } }

不用 Spring Security 和 Shiro                    ,是不是更简单呢!

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
nexus 仓库地址(Nexus私有maven库部署和使用) 如何打造高质量网站(从网站建设到内容优化,教你打造让用户爱不释手的网站)