Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions SpringBoot-JWT -kimi-update/.gitignore
Original file line number Diff line number Diff line change
@@ -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/
104 changes: 104 additions & 0 deletions SpringBoot-JWT -kimi-update/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>
<groupId>top.lrshuai</groupId>
<artifactId>jwt</artifactId>
<version>1.0.0</version>
<name>jwt</name>
<description>Modern JWT Authentication System for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<jjwt.version>0.11.5</jjwt.version>
<springdoc.version>1.7.0</springdoc.version>
</properties>

<dependencies>
<!-- Spring Boot Starters -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- JJWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>

<!-- SpringDoc OpenAPI (Swagger) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>

<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<!-- Apache Commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>

<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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<T> {

@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 <T> Result<T> success() {
Result<T> result = new Result<>();
result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(ResultCode.SUCCESS.getMessage());
return result;
}

public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(ResultCode.SUCCESS.getMessage());
result.setData(data);
return result;
}

public static <T> Result<T> success(String message, T data) {
Result<T> result = new Result<>();
result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(message);
result.setData(data);
return result;
}

public static <T> Result<T> error() {
Result<T> result = new Result<>();
result.setCode(ResultCode.ERROR.getCode());
result.setMessage(ResultCode.ERROR.getMessage());
return result;
}

public static <T> Result<T> error(String message) {
Result<T> result = new Result<>();
result.setCode(ResultCode.ERROR.getCode());
result.setMessage(message);
return result;
}

public static <T> Result<T> error(int code, String message) {
Result<T> result = new Result<>();
result.setCode(code);
result.setMessage(message);
return result;
}

public static <T> Result<T> error(ResultCode resultCode) {
Result<T> result = new Result<>();
result.setCode(resultCode.getCode());
result.setMessage(resultCode.getMessage());
return result;
}

public static <T> Result<T> error(ResultCode resultCode, String message) {
Result<T> result = new Result<>();
result.setCode(resultCode.getCode());
result.setMessage(message);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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";
}
Original file line number Diff line number Diff line change
@@ -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")));
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading