Skip to content

Commit 3e6a5ca

Browse files
committed
双Token(数据库待修改)
1 parent 31cef85 commit 3e6a5ca

16 files changed

Lines changed: 435 additions & 46 deletions

File tree

drawbluecup-common/pom.xml

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,53 @@
1818
<groupId>org.springframework</groupId>
1919
<artifactId>spring-context</artifactId>
2020
</dependency>
21-
<!-- Spring Web(用于 HTTP 状态码、Controller 等) -->
21+
22+
<!-- Spring Web(适配Spring Boot 3,包含Jakarta EE) -->
2223
<dependency>
2324
<groupId>org.springframework.boot</groupId>
2425
<artifactId>spring-boot-starter-web</artifactId>
2526
</dependency>
26-
<!-- Bean Validation API,供自定义注解使用 -->
27+
28+
<!-- 校验框架(包含Validator实现,避免自定义注解无法生效) -->
2729
<dependency>
28-
<groupId>jakarta.validation</groupId>
29-
<artifactId>jakarta.validation-api</artifactId>
30+
<groupId>org.springframework.boot</groupId>
31+
<artifactId>spring-boot-starter-validation</artifactId>
3032
</dependency>
33+
34+
<!-- Lombok -->
3135
<dependency>
3236
<groupId>org.projectlombok</groupId>
3337
<artifactId>lombok</artifactId>
3438
<scope>provided</scope>
3539
</dependency>
40+
41+
<!-- JWT核心依赖(指定版本,适配Spring Boot 3) -->
42+
<dependency>
43+
<groupId>io.jsonwebtoken</groupId>
44+
<artifactId>jjwt-api</artifactId>
45+
46+
</dependency>
3647
<dependency>
37-
<groupId>com.mysql</groupId>
38-
<artifactId>mysql-connector-j</artifactId>
48+
<groupId>io.jsonwebtoken</groupId>
49+
<artifactId>jjwt-impl</artifactId>
50+
51+
<scope>runtime</scope>
52+
</dependency>
53+
<dependency>
54+
<groupId>io.jsonwebtoken</groupId>
55+
<artifactId>jjwt-jackson</artifactId>
56+
57+
<scope>runtime</scope>
3958
</dependency>
59+
60+
<!-- 密码加密(BCrypt) -->
61+
<dependency>
62+
<groupId>org.springframework.security</groupId>
63+
<artifactId>spring-security-crypto</artifactId>
64+
<version>6.2.0</version>
65+
</dependency>
66+
67+
<!-- Swagger注解(Jakarta版) -->
4068
<dependency>
4169
<groupId>io.swagger.core.v3</groupId>
4270
<artifactId>swagger-annotations-jakarta</artifactId>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.drawbluecup.JWT;
2+
3+
4+
import io.jsonwebtoken.Jwts;
5+
import io.jsonwebtoken.security.Keys;
6+
import javax.crypto.SecretKey; // 临时兼容(JDK 17仍保留javax.crypto)
7+
import java.util.Date;
8+
import java.util.Map;
9+
10+
/**
11+
* JWT工具类:新增双Token过期时间常量
12+
*/
13+
public class JwtUtils {
14+
// 密钥(生产环境建议用32位随机字符串,且保密)
15+
private static final String SECRET = "12345678901234567890123456789012";
16+
17+
// ========== 新增:双Token过期时间 ==========
18+
public static final long ACCESS_TOKEN_EXPIRE = 2 * 60 * 60 * 1000; // Access Token:2小时
19+
public static final long REFRESH_TOKEN_EXPIRE = 7 * 24 * 60 * 60 * 1000; // Refresh Token:7天
20+
21+
22+
//==============================方法==================================//
23+
24+
/**
25+
* 生成加密密钥
26+
*/
27+
private static SecretKey getKey() {
28+
return Keys.hmacShaKeyFor(SECRET.getBytes());
29+
}
30+
31+
/**
32+
* 生成Token(通用方法,支持Access/Refresh Token)
33+
* @param userInfo 存入Token的用户信息(如userId、phone)
34+
* @param expireTime 过期时间(毫秒)
35+
* @return JWT Token字符串
36+
*/
37+
public static String generateToken(Map<String, Object> userInfo, long expireTime) {
38+
return Jwts.builder()
39+
.setClaims(userInfo) // 存入用户信息(Payload)
40+
.setExpiration(new Date(System.currentTimeMillis() + expireTime)) // 过期时间
41+
.signWith(getKey()) // 签名(防篡改)
42+
.compact();
43+
}
44+
45+
/**
46+
* 解析Token
47+
* @param token 前端传入的Token字符串
48+
* @return Token中的用户信息(如userId)
49+
* @throws RuntimeException Token无效/过期时抛出异常
50+
*/
51+
public static Map<String, Object> parseToken(String token) {
52+
try {
53+
return Jwts.parserBuilder()
54+
.setSigningKey(getKey()) // 用相同密钥验证
55+
.build()
56+
.parseClaimsJws(token) // 解析Token
57+
.getBody(); // 获取Payload中的用户信息
58+
} catch (Exception e) {
59+
throw new RuntimeException("Token无效或已过期:" + e.getMessage());
60+
}
61+
}
62+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.drawbluecup.JWT;
2+
3+
import org.springframework.web.servlet.HandlerInterceptor;
4+
import jakarta.servlet.http.HttpServletRequest;
5+
import jakarta.servlet.http.HttpServletResponse;//修正拦截器的包导入(把javax换成jakarta)
6+
import java.util.Map;
7+
8+
/**
9+
* Token拦截器:仅校验Access Token(Refresh Token接口不拦截)
10+
*/
11+
public class TokenInterceptor implements HandlerInterceptor {
12+
@Override
13+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
14+
// 1. 排除登录接口、刷新Token接口(无需校验Access Token)
15+
String requestUrl = request.getRequestURI();
16+
if (requestUrl.contains("/login") || requestUrl.contains("/refreshToken")) {
17+
return true; // 放行
18+
}
19+
20+
// 2. 从请求头获取Access Token(约定前端字段名:Access-Token)
21+
String accessToken = request.getHeader("Access-Token");
22+
if (accessToken == null || accessToken.isEmpty()) {
23+
// 手动返回错误响应
24+
response.setCharacterEncoding("UTF-8");
25+
response.setContentType("application/json");
26+
response.getWriter().write("{\"code\":401,\"message\":\"Access Token为空,请先登录\"}");
27+
return false; // 拒绝放行
28+
}
29+
30+
// 3. 排除静态资源(仅拦截Controller接口)
31+
if (!(handler instanceof org.springframework.web.method.HandlerMethod)) {
32+
return true;
33+
}
34+
35+
// 4. 解析Access Token(验证有效性),并提取用户信息
36+
Map<String, Object> userInfo = JwtUtils.parseToken(accessToken);
37+
Integer userId = (Integer) userInfo.get("userId");
38+
// 将用户ID存入request,供后续接口使用!!
39+
request.setAttribute("loginUserId", userId);
40+
41+
return true; // 校验通过,放行
42+
}
43+
}

drawbluecup-common/src/main/java/com/drawbluecup/dto/product/ProductRespDTO.java renamed to drawbluecup-common/src/main/java/com/drawbluecup/dto/product/ProductRespDTOWithout.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
@Data
1111
@Schema(name = "ProductRespDTO", description = "商品信息出参")// Swagger注解:文档里说明这个DTO的作用
1212

13-
public class ProductRespDTO {
13+
public class ProductRespDTOWithout {
1414

1515
@Schema(description = "商品ID")// 文档里标注字段说明
1616
private Integer id; // 前端需要看的id
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.drawbluecup.dto.user.LoginAndToken;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* 登录入参DTO
7+
*/
8+
@Data
9+
public class UserLoginDTO {
10+
private String phone;
11+
private String password;
12+
}
13+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.drawbluecup.dto.user.LoginAndToken;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* 登录出参DTO(返回双Token)
7+
*/
8+
@Data
9+
public class UserLoginRespDTO {
10+
private String accessToken;
11+
private String refreshToken;
12+
private String userName;
13+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.drawbluecup.dto.user.LoginAndToken;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* 刷新Token入参DTO
7+
*/
8+
@Data
9+
public class UserRefreshTokenDTO {
10+
private String refreshToken;
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.drawbluecup.dto.user.LoginAndToken;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* 刷新Token出参DTO
7+
*/
8+
@Data
9+
public class UserRefreshTokenRespDTO {
10+
private String newAccessToken;
11+
12+
}

drawbluecup-common/src/main/java/com/drawbluecup/dto/user/UserRespDTO.java

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.drawbluecup.dto.user;
2+
3+
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import lombok.Data;
6+
7+
import java.time.LocalDateTime;
8+
9+
10+
@Data
11+
@Schema(name = "UserRespDTOWithout", description = "用户信息出参(仅用户)")// Swagger注解:文档里说明这个DTO的作用
12+
13+
public class UserRespDTOWithout {
14+
@Schema(description = "用户主键id")
15+
private Integer id;
16+
@Schema(description = "用户名称")
17+
private String name;
18+
@Schema(description = "用户电话")
19+
private String phone;
20+
@Schema(description = "用户创建时间")
21+
private LocalDateTime createTime;
22+
@Schema(description = "用户更新时间")
23+
private LocalDateTime updateTime;
24+
25+
}

0 commit comments

Comments
 (0)