fix: 确保项目可以启动

This commit is contained in:
2025-12-12 23:50:55 +08:00
parent c61ee69561
commit 4912e48922
21 changed files with 623 additions and 145 deletions

View File

@@ -19,40 +19,51 @@
</properties>
<dependencies>
<!-- 核心模块 -->
<dependency>
<groupId>cn.meowrain</groupId>
<artifactId>aioj-backend-common-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.meowrain</groupId>
<artifactId>aioj-backend-common-feign</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- spring cloud发现服务-->
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- Spring Cloud服务发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- OAuth2 Client -->
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- OAuth2 & Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--JWT-->
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
@@ -70,37 +81,42 @@
<version>0.13.0</version>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-openapi3-jakarta-spring-boot-starter -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<!--
引用通用模块
-->
<dependency>
<groupId>cn.meowrain</groupId>
<artifactId>aioj-backend-common-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!--引入openfeign-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<!-- Feign客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>4.3.0</version>
</dependency>
<!-- 引入redis存储refreshToken-->
<!-- Redis用于存储refreshToken -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- API文档 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<!-- 开发工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -13,6 +13,6 @@ public interface UserClient {
Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount);
@GetMapping("/inner/get-by-userid")
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userid);
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userId);
}

View File

@@ -3,8 +3,9 @@ package cn.meowrain.aioj.backend.auth.controller;
import cn.meowrain.aioj.backend.auth.dto.req.UserLoginRequestDTO;
import cn.meowrain.aioj.backend.auth.dto.resp.UserLoginResponseDTO;
import cn.meowrain.aioj.backend.auth.service.AuthService;
import cn.meowrain.aioj.backend.framework.web.Results;
import cn.meowrain.aioj.backend.framework.web.Result;
import cn.meowrain.aioj.backend.framework.core.web.Result;
import cn.meowrain.aioj.backend.framework.core.web.Results;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@@ -33,4 +34,16 @@ public class AuthController {
return Results.success(userLoginResponseDTO.getAccessToken());
}
@PostMapping("/validate")
public Result<Boolean> validate(@RequestHeader(value = "Authorization", required = false) String authorization) {
// 从Authorization头中提取Bearer token
String token = null;
if (authorization != null && authorization.startsWith("Bearer ")) {
token = authorization.substring(7);
}
Boolean isValid = authService.validateToken(token);
return Results.success(isValid);
}
}

View File

@@ -2,9 +2,10 @@ package cn.meowrain.aioj.backend.auth.dto.chains;
import cn.meowrain.aioj.backend.auth.common.enums.ChainMarkEnums;
import cn.meowrain.aioj.backend.auth.dto.req.UserLoginRequestDTO;
import cn.meowrain.aioj.backend.framework.designpattern.chains.AbstractChianHandler;
import cn.meowrain.aioj.backend.framework.errorcode.ErrorCode;
import cn.meowrain.aioj.backend.framework.exception.ClientException;
import cn.meowrain.aioj.backend.framework.core.designpattern.chains.AbstractChianHandler;
import cn.meowrain.aioj.backend.framework.core.errorcode.ErrorCode;
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

View File

@@ -19,4 +19,11 @@ public interface AuthService {
*/
UserLoginResponseDTO refreshToken(String refreshToken);
/**
* 验证token的有效性
* @param accessToken 访问令牌
* @return token是否有效
*/
Boolean validateToken(String accessToken);
}

View File

@@ -39,23 +39,37 @@ public class AuthServiceImpl implements AuthService {
@Override
public UserLoginResponseDTO userLogin(UserLoginRequestDTO requestParam) {
log.info("用户登录请求: userAccount={}", requestParam.getUserAccount());
// 1.校验
userLoginRequestParamVerifyContext.handler(ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName(),
requestParam);
// 如果调用user-service失败那么就说明是系统内部错误
log.info("正在调用user-service查询用户信息...");
Result<UserAuthRespDTO> userResp = userClient.getUserByUserName(requestParam.getUserAccount());
if (userResp.isFail()) {
log.error("调用user-service返回失败{}", userResp.getMessage());
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
}
UserAuthRespDTO user = userResp.getData();
if (ObjectUtil.isNull(user) || !BCrypt.checkpw(requestParam.getUserPassword(), user.getUserPassword())) {
throw new ServiceException("用户不存在或者密码错误", ErrorCode.NOT_LOGIN_ERROR);
UserAuthRespDTO user = userResp.getData();
if (user == null) {
log.warn("用户不存在: {}", requestParam.getUserAccount());
throw new ServiceException("用户不存在或密码错误", ErrorCode.NOT_LOGIN_ERROR);
}
if (!BCrypt.checkpw(requestParam.getUserPassword(), user.getUserPassword())) {
log.warn("密码错误: {}", requestParam.getUserAccount());
throw new ServiceException("用户不存在或密码错误", ErrorCode.NOT_LOGIN_ERROR);
}
// 生成 JWT
log.info("正在生成JWT token...");
String accessToken = jwtUtil.generateAccessToken(user);
String refreshToken = jwtUtil.generateRefreshToken(user.getId());
UserLoginResponseDTO resp = new UserLoginResponseDTO();
resp.setId(user.getId());
resp.setUserAccount(user.getUserAccount());
@@ -66,6 +80,8 @@ public class AuthServiceImpl implements AuthService {
stringRedisTemplate.opsForValue()
.set(String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, user.getId()), refreshToken,
jwtPropertiesConfiguration.getRefreshExpire(), TimeUnit.MILLISECONDS);
log.info("用户登录成功: userId={}, userAccount={}", user.getId(), user.getUserAccount());
return resp;
}
@@ -106,4 +122,46 @@ public class AuthServiceImpl implements AuthService {
return userLoginResponseDTO;
}
/**
* 验证token的有效性
* @param accessToken 访问令牌
* @return token是否有效
*/
@Override
public Boolean validateToken(String accessToken) {
try {
// 1. 检查token格式
if (accessToken == null || accessToken.trim().isEmpty()) {
log.warn("Access token is null or empty");
return false;
}
// 2. 验证token签名和过期时间
if (!jwtUtil.isTokenValid(accessToken)) {
log.warn("Access token is invalid or expired");
return false;
}
// 3. 解析token获取用户信息
String userId = jwtUtil.parseClaims(accessToken).getSubject();
if (userId == null) {
log.warn("Access token does not contain valid user id");
return false;
}
// 4. 验证用户是否存在(可选,增加安全性)
Result<UserAuthRespDTO> userResult = userClient.getUserById(userId);
if (userResult.isFail() || userResult.getData() == null) {
log.warn("User not found for id: {}", userId);
return false;
}
log.debug("Access token validation successful for user: {}", userId);
return true;
} catch (Exception e) {
log.error("Error validating access token", e);
return false;
}
}
}