diff --git a/chaos_api_common/src/main/java/cn/nopj/chaos_api/common/constants/ErrorCode.java b/chaos_api_common/src/main/java/cn/nopj/chaos_api/common/constants/ErrorCode.java index 1c2b0fd..fd2475d 100644 --- a/chaos_api_common/src/main/java/cn/nopj/chaos_api/common/constants/ErrorCode.java +++ b/chaos_api_common/src/main/java/cn/nopj/chaos_api/common/constants/ErrorCode.java @@ -21,6 +21,9 @@ public enum ErrorCode { PASSWORD_FORMAT_ERROR(400, "USER-104", "密码需6-20位字符组合"), USER_NOT_EXISTS(404, "USER-104", "用户不存在"), USER_ID_INVALID(400, "USER-105", "用户ID无效"), + + USER_NOT_EXISTS_OR_PASSWORD_WRONG(401, "USER-105", "用户名不存在或密码错误"), + USER_NOT_ENABLED(403, "USER-106", "用户未启用"), USER_NOT_LOGIN(401, "USER-105", "请先登录"), USER_BANNED(403, "USER-106", "账号已被封禁"), EMAIL_EXISTS(409, "USER-107", "邮箱已注册"), @@ -37,10 +40,11 @@ public enum ErrorCode { COMMENT_TOO_LONG(400, "POST-206", "评论超过500字限制"), // ================== 系统/第三方 (300-399) ================== + SYSTEM_ERROR(500, "SYS-300", "系统错误"), CAPTCHA_ERROR(400, "SYS-301", "验证码错误"), SMS_SEND_FAILED(500, "SYS-302", "短信发送失败"), FILE_UPLOAD_FAILED(500, "SYS-303", "文件上传失败"), - RATE_LIMIT_EXCEEDED(429, "SYS-304", "操作过于频繁"), ; + RATE_LIMIT_EXCEEDED(429, "SYS-304", "操作过于频繁"); private final int httpStatus; private final String code; // 业务错误码(领域-编号) diff --git a/chaos_api_domain/src/main/java/cn/nopj/chaos_api/dto/response/AuthTokenResponse.java b/chaos_api_domain/src/main/java/cn/nopj/chaos_api/dto/response/AuthTokenResponse.java new file mode 100644 index 0000000..b9d01b3 --- /dev/null +++ b/chaos_api_domain/src/main/java/cn/nopj/chaos_api/dto/response/AuthTokenResponse.java @@ -0,0 +1,10 @@ +package cn.nopj.chaos_api.dto.response; + +import lombok.Data; + +@Data + +public class AuthTokenResponse { + private String tokenHead; + private String token; +} diff --git a/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/AuthController.java b/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/AuthController.java index 83d6118..75faa7e 100644 --- a/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/AuthController.java +++ b/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/AuthController.java @@ -3,22 +3,19 @@ package cn.nopj.chaos_api.controller; import cn.nopj.chaos_api.converter.UserConverter; import cn.nopj.chaos_api.dto.request.AuthLoginRequest; import cn.nopj.chaos_api.dto.request.AuthRegisterRequest; +import cn.nopj.chaos_api.dto.response.AuthTokenResponse; import cn.nopj.chaos_api.model.ApiResult; import cn.nopj.chaos_api.service.AuthService; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.HashMap; -import java.util.Map; - /** - * 认证控管理 + * 认证管理 * */ @RestController @@ -27,8 +24,7 @@ public class AuthController { @Autowired private AuthService authService; - @Value("${jwt.tokenHead}") - private String tokenHead; + @Autowired private UserConverter userConverter; @@ -49,15 +45,7 @@ public class AuthController { * @return 登录结果 */ @PostMapping("/login") - public ApiResult login(@RequestBody AuthLoginRequest authLoginRequest) { - - String token = authService.login(authLoginRequest.getUsername(), authLoginRequest.getPassword()); - - Map tokenMap = new HashMap<>(); - tokenMap.put("token", token); - tokenMap.put("tokenHead", tokenHead); - return ApiResult.success(tokenMap); - - + public ApiResult login(@RequestBody AuthLoginRequest authLoginRequest) { + return ApiResult.success(authService.login(authLoginRequest.getUsername(), authLoginRequest.getPassword())); } } diff --git a/chaos_api_web/src/main/java/cn/nopj/chaos_api/exception/GlobalExceptionHandler.java b/chaos_api_web/src/main/java/cn/nopj/chaos_api/exception/GlobalExceptionHandler.java index 085b00e..ba9ab95 100644 --- a/chaos_api_web/src/main/java/cn/nopj/chaos_api/exception/GlobalExceptionHandler.java +++ b/chaos_api_web/src/main/java/cn/nopj/chaos_api/exception/GlobalExceptionHandler.java @@ -5,6 +5,7 @@ import cn.nopj.chaos_api.model.ApiResult; import lombok.extern.slf4j.Slf4j; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; +import org.springframework.security.authorization.AuthorizationDeniedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -40,4 +41,10 @@ public class GlobalExceptionHandler { log.error("服务器内部错误", ex); return ApiResult.failed("服务器内部错误,请联系管理员"); } + + @ExceptionHandler(AuthorizationDeniedException.class) + public ApiResult handleAuthorizationDeniedException(AuthorizationDeniedException ex) { + + return ApiResult.failed("权限不足,请求已登记"); + } } diff --git a/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/AuthService.java b/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/AuthService.java index 4f4119d..6021f2b 100644 --- a/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/AuthService.java +++ b/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/AuthService.java @@ -1,6 +1,7 @@ package cn.nopj.chaos_api.service; import cn.nopj.chaos_api.domain.entity.User; +import cn.nopj.chaos_api.dto.response.AuthTokenResponse; public interface AuthService { /** @@ -12,5 +13,5 @@ public interface AuthService { * 登录 * @return 生成的 JWT token */ - String login(String username, String password); + AuthTokenResponse login(String username, String password); } diff --git a/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/impl/AuthServiceImpl.java b/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/impl/AuthServiceImpl.java index d3e00b4..cdf9298 100644 --- a/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/impl/AuthServiceImpl.java +++ b/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/impl/AuthServiceImpl.java @@ -4,12 +4,16 @@ package cn.nopj.chaos_api.service.impl; import cn.nopj.chaos_api.common.constants.ErrorCode; import cn.nopj.chaos_api.common.exceotion.BizException; import cn.nopj.chaos_api.domain.entity.User; +import cn.nopj.chaos_api.dto.response.AuthTokenResponse; import cn.nopj.chaos_api.mapper.UserMapper; import cn.nopj.chaos_api.service.AuthService; import cn.nopj.chaos_api.util.JwtTokenUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.DisabledException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -30,7 +34,8 @@ public class AuthServiceImpl implements AuthService { private JwtTokenUtil jwtTokenUtil; @Autowired private AuthenticationManager authenticationManager; - + @Value("${jwt.tokenHead}") + private String tokenHead; @Override public User register(User user) { @@ -49,7 +54,7 @@ public class AuthServiceImpl implements AuthService { } @Override - public String login(String username, String password) { + public AuthTokenResponse login(String username, String password) { // 尝试进行身份验证 try{ Authentication authentication = authenticationManager.authenticate( @@ -57,20 +62,24 @@ public class AuthServiceImpl implements AuthService { ); // 将认证结果保存在 SecurityContextHolder 中 - SecurityContextHolder.getContext().setAuthentication(authentication); // 获取用户详情 UserDetails userDetails = (UserDetails) authentication.getPrincipal(); if (!userDetails.isEnabled()) { - return null; + throw new BizException(ErrorCode.USER_NOT_ENABLED); } - // 生成 JWT - return jwtTokenUtil.generateToken(userDetails); - }catch (Exception e){ + AuthTokenResponse res = new AuthTokenResponse(); + res.setToken(jwtTokenUtil.generateToken(userDetails)); + res.setTokenHead(tokenHead); + return res; - throw new BizException(ErrorCode.USER_NOT_EXISTS); + }catch (BadCredentialsException e) { + throw new BizException(ErrorCode.USER_NOT_EXISTS_OR_PASSWORD_WRONG); + } catch (DisabledException e) { + throw new BizException(ErrorCode.USER_NOT_ENABLED); + } catch (Exception e) { + throw new BizException(ErrorCode.SYSTEM_ERROR); } - } } \ No newline at end of file