diff --git a/SpringBoot-JWT -kimi-update/.gitignore b/SpringBoot-JWT -kimi-update/.gitignore
new file mode 100644
index 0000000..153c933
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/.gitignore
@@ -0,0 +1,29 @@
+HELP.md
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+/build/
+
+### VS Code ###
+.vscode/
diff --git a/SpringBoot-JWT -kimi-update/pom.xml b/SpringBoot-JWT -kimi-update/pom.xml
new file mode 100644
index 0000000..cbe13ea
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/pom.xml
@@ -0,0 +1,104 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.18
+
+
+ top.lrshuai
+ jwt
+ 1.0.0
+ jwt
+ Modern JWT Authentication System for Spring Boot
+
+
+ 1.8
+ 0.11.5
+ 1.7.0
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ ${jjwt.version}
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ ${jjwt.version}
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ ${jjwt.version}
+ runtime
+
+
+
+
+ org.springdoc
+ springdoc-openapi-ui
+ ${springdoc.version}
+
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
diff --git a/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/JwtApplication.java b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/JwtApplication.java
new file mode 100644
index 0000000..aac3348
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/JwtApplication.java
@@ -0,0 +1,16 @@
+package top.lrshuai.jwt;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import top.lrshuai.jwt.config.JwtProperties;
+
+@SpringBootApplication
+@EnableConfigurationProperties(JwtProperties.class)
+public class JwtApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(JwtApplication.class, args);
+ }
+
+}
diff --git a/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/common/Result.java b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/common/Result.java
new file mode 100644
index 0000000..f17e0ec
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/common/Result.java
@@ -0,0 +1,88 @@
+package top.lrshuai.jwt.common;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@Schema(description = "统一响应结果")
+public class Result {
+
+ @Schema(description = "状态码", example = "200")
+ private Integer code;
+
+ @Schema(description = "响应消息", example = "操作成功")
+ private String message;
+
+ @Schema(description = "响应数据")
+ private T data;
+
+ @Schema(description = "时间戳")
+ private LocalDateTime timestamp;
+
+ @Schema(description = "请求路径")
+ private String path;
+
+ public Result() {
+ this.timestamp = LocalDateTime.now();
+ }
+
+ public static Result success() {
+ Result result = new Result<>();
+ result.setCode(ResultCode.SUCCESS.getCode());
+ result.setMessage(ResultCode.SUCCESS.getMessage());
+ return result;
+ }
+
+ public static Result success(T data) {
+ Result result = new Result<>();
+ result.setCode(ResultCode.SUCCESS.getCode());
+ result.setMessage(ResultCode.SUCCESS.getMessage());
+ result.setData(data);
+ return result;
+ }
+
+ public static Result success(String message, T data) {
+ Result result = new Result<>();
+ result.setCode(ResultCode.SUCCESS.getCode());
+ result.setMessage(message);
+ result.setData(data);
+ return result;
+ }
+
+ public static Result error() {
+ Result result = new Result<>();
+ result.setCode(ResultCode.ERROR.getCode());
+ result.setMessage(ResultCode.ERROR.getMessage());
+ return result;
+ }
+
+ public static Result error(String message) {
+ Result result = new Result<>();
+ result.setCode(ResultCode.ERROR.getCode());
+ result.setMessage(message);
+ return result;
+ }
+
+ public static Result error(int code, String message) {
+ Result result = new Result<>();
+ result.setCode(code);
+ result.setMessage(message);
+ return result;
+ }
+
+ public static Result error(ResultCode resultCode) {
+ Result result = new Result<>();
+ result.setCode(resultCode.getCode());
+ result.setMessage(resultCode.getMessage());
+ return result;
+ }
+
+ public static Result error(ResultCode resultCode, String message) {
+ Result result = new Result<>();
+ result.setCode(resultCode.getCode());
+ result.setMessage(message);
+ return result;
+ }
+}
diff --git a/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/common/ResultCode.java b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/common/ResultCode.java
new file mode 100644
index 0000000..3c49707
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/common/ResultCode.java
@@ -0,0 +1,43 @@
+package top.lrshuai.jwt.common;
+
+import lombok.Getter;
+
+@Getter
+public enum ResultCode {
+
+ SUCCESS(200, "操作成功"),
+ ERROR(500, "系统错误"),
+
+ // 认证相关 1000-1099
+ UNAUTHORIZED(401, "未授权,请先登录"),
+ FORBIDDEN(403, "无权限访问该资源"),
+ TOKEN_EXPIRED(1001, "Token已过期"),
+ TOKEN_INVALID(1002, "Token无效"),
+ TOKEN_REVOKED(1003, "Token已被吊销"),
+ REFRESH_TOKEN_EXPIRED(1004, "Refresh Token已过期"),
+
+ // 用户相关 1100-1199
+ USER_NOT_FOUND(1100, "用户不存在"),
+ USERNAME_EXISTS(1101, "用户名已存在"),
+ EMAIL_EXISTS(1102, "邮箱已被注册"),
+ PHONE_EXISTS(1103, "手机号已被注册"),
+ PASSWORD_ERROR(1104, "密码错误"),
+ ACCOUNT_LOCKED(1105, "账号已被锁定"),
+ ACCOUNT_DISABLED(1106, "账号已被禁用"),
+
+ // 验证码相关 1200-1299
+ CAPTCHA_ERROR(1200, "验证码错误"),
+ CAPTCHA_EXPIRED(1201, "验证码已过期"),
+
+ // 参数相关 1300-1399
+ PARAM_ERROR(1300, "参数错误"),
+ PARAM_MISSING(1301, "缺少必要参数");
+
+ private final int code;
+ private final String message;
+
+ ResultCode(int code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+}
diff --git a/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/JwtProperties.java b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/JwtProperties.java
new file mode 100644
index 0000000..5d5aac2
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/JwtProperties.java
@@ -0,0 +1,19 @@
+package top.lrshuai.jwt.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "jwt")
+public class JwtProperties {
+
+ private String secret = "your-256-bit-secret-key-for-jwt-signing-must-be-at-least-32-characters-long";
+ private String issuer = "jwt-system";
+ private String audience = "web-app";
+ private Long accessTokenExpire = 7200L;
+ private Long refreshTokenExpire = 604800L;
+ private String tokenPrefix = "Bearer ";
+ private String headerName = "Authorization";
+}
diff --git a/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/OpenApiConfig.java b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/OpenApiConfig.java
new file mode 100644
index 0000000..79f4d83
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/OpenApiConfig.java
@@ -0,0 +1,37 @@
+package top.lrshuai.jwt.config;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class OpenApiConfig {
+
+ @Bean
+ public OpenAPI customOpenAPI() {
+ return new OpenAPI()
+ .info(new Info()
+ .title("JWT认证系统 API")
+ .version("1.0.0")
+ .description("基于Spring Boot的现代化JWT认证系统,支持双Token机制、用户管理、权限控制等功能")
+ .contact(new Contact()
+ .name("JWT System")
+ .email("support@example.com"))
+ .license(new License()
+ .name("Apache 2.0")
+ .url("https://www.apache.org/licenses/LICENSE-2.0")))
+ .addSecurityItem(new SecurityRequirement().addList("bearerAuth"))
+ .components(new Components()
+ .addSecuritySchemes("bearerAuth", new SecurityScheme()
+ .name("bearerAuth")
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .bearerFormat("JWT")));
+ }
+}
diff --git a/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/WebConfig.java b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/WebConfig.java
new file mode 100644
index 0000000..a322293
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/config/WebConfig.java
@@ -0,0 +1,52 @@
+package top.lrshuai.jwt.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+import top.lrshuai.jwt.interceptor.JwtInterceptor;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+ @Autowired
+ private JwtInterceptor jwtInterceptor;
+
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOriginPatterns("*")
+ .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")
+ .allowedHeaders("*")
+ .allowCredentials(true)
+ .maxAge(3600);
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(jwtInterceptor)
+ .addPathPatterns("/api/v1/**")
+ .excludePathPatterns(
+ "/api/v1/auth/login",
+ "/api/v1/auth/register",
+ "/api/v1/auth/refresh",
+ "/api/v1/auth/captcha",
+ "/api/v1/token/verify",
+ "/api/v1/token/parse",
+ "/swagger-ui/**",
+ "/swagger-ui.html",
+ "/v3/api-docs/**",
+ "/webjars/**",
+ "/error"
+ );
+ }
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/swagger-ui/**")
+ .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
+ .resourceChain(false);
+ }
+}
diff --git a/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/controller/AuthController.java b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/controller/AuthController.java
new file mode 100644
index 0000000..404702d
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/controller/AuthController.java
@@ -0,0 +1,64 @@
+package top.lrshuai.jwt.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import top.lrshuai.jwt.common.Result;
+import top.lrshuai.jwt.dto.*;
+import top.lrshuai.jwt.service.AuthService;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("/api/v1/auth")
+@Tag(name = "认证管理", description = "用户认证相关接口:登录、注册、登出、刷新Token等")
+@Validated
+public class AuthController {
+
+ @Autowired
+ private AuthService authService;
+
+ @PostMapping("/login")
+ @Operation(summary = "用户登录", description = "用户登录接口,支持用户名密码登录")
+ public Result login(@Valid @RequestBody LoginRequest request) {
+ return Result.success(authService.login(request));
+ }
+
+ @PostMapping("/register")
+ @Operation(summary = "用户注册", description = "用户注册接口,需要用户名、密码、确认密码,可选邮箱和手机号")
+ public Result register(@Valid @RequestBody RegisterRequest request) {
+ authService.register(request);
+ return Result.success("注册成功");
+ }
+
+ @PostMapping("/logout")
+ @Operation(summary = "用户登出", description = "用户登出接口,需要传入Authorization头")
+ public Result logout(HttpServletRequest request) {
+ String token = extractTokenFromRequest(request);
+ Long userId = getCurrentUserId(request);
+ authService.logout(userId, token);
+ return Result.success("登出成功");
+ }
+
+ @PostMapping("/refresh")
+ @Operation(summary = "刷新Token", description = "使用Refresh Token获取新的Access Token和Refresh Token")
+ public Result refreshToken(@Valid @RequestBody RefreshTokenRequest request) {
+ return Result.success(authService.refreshToken(request));
+ }
+
+ private String extractTokenFromRequest(HttpServletRequest request) {
+ String bearerToken = request.getHeader("Authorization");
+ if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
+ return bearerToken.substring(7);
+ }
+ return null;
+ }
+
+ private Long getCurrentUserId(HttpServletRequest request) {
+ Object userId = request.getAttribute("userId");
+ return userId != null ? Long.valueOf(userId.toString()) : null;
+ }
+}
diff --git a/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/controller/PermissionController.java b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/controller/PermissionController.java
new file mode 100644
index 0000000..56dbc5f
--- /dev/null
+++ b/SpringBoot-JWT -kimi-update/src/main/java/top/lrshuai/jwt/controller/PermissionController.java
@@ -0,0 +1,55 @@
+package top.lrshuai.jwt.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import top.lrshuai.jwt.common.Result;
+import top.lrshuai.jwt.service.AuthService;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/v1")
+@Tag(name = "权限管理", description = "用户权限和角色查询接口")
+@Validated
+@SecurityRequirement(name = "bearerAuth")
+public class PermissionController {
+
+ @Autowired
+ private AuthService authService;
+
+ @GetMapping("/permissions")
+ @Operation(summary = "获取当前用户权限", description = "获取当前登录用户的所有权限列表")
+ public Result