refactor(auth):重构认证模块并增强验证机制
- 重命名并调整 DTO 类结构,将 LoginRequest 和 RegisterRequest 迁移至 request 包- 引入 AuthLoginRequest 和 AuthRegisterRequest 并添加字段验证注解 - 更新 AuthController 使用新的 DTO 并增加 @Valid 参数校验 - 修改 AuthService 接口及实现类,接收 User 实体而非 RegisterRequest - 添加全局异常处理器 GlobalExceptionHandler 处理参数校验和业务异常 - 新增 ErrorCode 枚举统一管理错误码和消息 - 引入 UserConverter 组件用于 DTO 到实体的转换 - 增强用户注册与登录逻辑,完善异常处理和错误提示 - 移除旧的 BadCredentialsException 捕获逻辑 - 调整 pom.xml 添加 spring-boot-starter-validation 和相关依赖 - 更新 User 实体类,添加完整字段映射和角色关联配置 - 新增 UserInfoService 及其实现,提供用户管理和密码设置功能 -优化 UserMapper 查询方法,支持联表查询用户及其角色信息 - 删除无用的 HLSController 控制器 - 完善 ImageController 文件上传逻辑并更新响应结构 - 添加用户名和密码格式验证工具类 PasswordValidate 和 UsernameValidate
This commit is contained in:
@@ -29,5 +29,21 @@
|
|||||||
<groupId>com.alibaba.fastjson2</groupId>
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
<artifactId>fastjson2</artifactId>
|
<artifactId>fastjson2</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.nopj</groupId>
|
||||||
|
<artifactId>chaos_api_domain</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package cn.nopj.chaos_api.common.constants;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局错误码枚举(HTTP状态码 + 业务错误码)
|
||||||
|
* 规范:
|
||||||
|
* - 4xx: 客户端错误
|
||||||
|
* - 5xx: 服务端错误
|
||||||
|
* - 业务码分段:
|
||||||
|
* 100-199: 用户相关
|
||||||
|
* 200-299: 帖子/评论相关
|
||||||
|
* 300-399: 系统/第三方服务
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum ErrorCode {
|
||||||
|
// ================== 用户相关 (100-199) ==================
|
||||||
|
USERNAME_EXISTS(409, "USER-101", "用户名已存在"),
|
||||||
|
USERNAME_FORMAT_ERROR(400, "USER-102", "用户名需5-20位字母数字组合"),
|
||||||
|
USERNAME_PATTERN_INVALID( 400, "USER-103" , "用户名格式无效,必须由字母、数字、下划线" ),
|
||||||
|
PASSWORD_FORMAT_ERROR(400, "USER-104", "密码需6-20位字符组合"),
|
||||||
|
USER_NOT_EXISTS(404, "USER-104", "用户不存在"),
|
||||||
|
USER_ID_INVALID(400, "USER-105", "用户ID无效"),
|
||||||
|
USER_NOT_LOGIN(401, "USER-105", "请先登录"),
|
||||||
|
USER_BANNED(403, "USER-106", "账号已被封禁"),
|
||||||
|
EMAIL_EXISTS(409, "USER-107", "邮箱已注册"),
|
||||||
|
EMAIL_FORMAT_ERROR(400, "USER-108", "邮箱格式无效"),
|
||||||
|
PHONE_EXISTS(409, "USER-109", "手机号已注册"),
|
||||||
|
PHONE_FORMAT_ERROR(400, "USER-110", "手机号格式无效"),
|
||||||
|
|
||||||
|
// ================== 论坛内容相关 (200-299) ==================
|
||||||
|
POST_NOT_FOUND(404, "POST-201", "帖子不存在"),
|
||||||
|
POST_DELETED(410, "POST-202", "帖子已被删除"),
|
||||||
|
POST_TITLE_EMPTY(400, "POST-203", "标题不能为空"),
|
||||||
|
POST_CONTENT_EMPTY(400, "POST-204", "内容不能为空"),
|
||||||
|
COMMENT_NOT_FOUND(404, "POST-205", "评论不存在"),
|
||||||
|
COMMENT_TOO_LONG(400, "POST-206", "评论超过500字限制"),
|
||||||
|
|
||||||
|
// ================== 系统/第三方 (300-399) ==================
|
||||||
|
CAPTCHA_ERROR(400, "SYS-301", "验证码错误"),
|
||||||
|
SMS_SEND_FAILED(500, "SYS-302", "短信发送失败"),
|
||||||
|
FILE_UPLOAD_FAILED(500, "SYS-303", "文件上传失败"),
|
||||||
|
RATE_LIMIT_EXCEEDED(429, "SYS-304", "操作过于频繁"), ;
|
||||||
|
|
||||||
|
private final int httpStatus;
|
||||||
|
private final String code; // 业务错误码(领域-编号)
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
ErrorCode(int httpStatus, String code, String message) {
|
||||||
|
this.httpStatus = httpStatus;
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package cn.nopj.chaos_api.common.exceotion;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.common.constants.ErrorCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class BizException extends RuntimeException{
|
||||||
|
public final ErrorCode errorCode;
|
||||||
|
|
||||||
|
public BizException(ErrorCode errorCode) {
|
||||||
|
super(errorCode.getMessage());
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package cn.nopj.chaos_api.converter;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.domain.entity.User;
|
||||||
|
import cn.nopj.chaos_api.dto.request.AuthRegisterRequest;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UserConverter {
|
||||||
|
public User convert(AuthRegisterRequest request){
|
||||||
|
User user = new User();
|
||||||
|
user.setUsername(request.getUsername());
|
||||||
|
user.setPassword(request.getPassword());
|
||||||
|
user.setEnabled(true);
|
||||||
|
user.setAccountNonExpired(true);
|
||||||
|
user.setCredentialsNonExpired(true);
|
||||||
|
user.setAccountNonLocked(true);
|
||||||
|
user.setCreateTime(java.time.LocalDateTime.now());
|
||||||
|
user.setUpdateTime(java.time.LocalDateTime.now());
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
package cn.nopj.chaos_api.mapper;
|
package cn.nopj.chaos_api.mapper;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.domain.entity.Role;
|
||||||
import cn.nopj.chaos_api.domain.entity.User;
|
import cn.nopj.chaos_api.domain.entity.User;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.*;
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -37,4 +36,51 @@ public interface UserMapper extends BaseMapper<User> {
|
|||||||
*/
|
*/
|
||||||
@Select("INSERT INTO t_user_role (user_id, role_id) VALUES (#{userId}, #{roleId})")
|
@Select("INSERT INTO t_user_role (user_id, role_id) VALUES (#{userId}, #{roleId})")
|
||||||
void insertUserRole(@Param("userId") Long id, @Param("roleId") Long i);
|
void insertUserRole(@Param("userId") Long id, @Param("roleId") Long i);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户名查询用户信息
|
||||||
|
* @param username 用户名
|
||||||
|
*/
|
||||||
|
@Select("SELECT * FROM t_user WHERE username = #{username}")
|
||||||
|
User selectByUsername(String username);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID查询用户信息和角色信息
|
||||||
|
*/
|
||||||
|
@Select("SELECT * FROM t_user WHERE id = #{id}")
|
||||||
|
@Results({
|
||||||
|
@Result(property = "roles", column = "id",
|
||||||
|
many = @Many(select = "findRolesByUserId"))
|
||||||
|
})
|
||||||
|
User findUserWithRoles(Long id);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有用户信息
|
||||||
|
* @return 所有用户信息
|
||||||
|
**/
|
||||||
|
@Select("""
|
||||||
|
SELECT * FROM t_user
|
||||||
|
""")
|
||||||
|
@Results({
|
||||||
|
@Result(id = true, property = "id", column = "id"),
|
||||||
|
@Result(property = "username", column = "username"),
|
||||||
|
@Result(property = "roles", column = "id",
|
||||||
|
many = @Many(select = "findRolesByUserId"))
|
||||||
|
})
|
||||||
|
List<User> findAllUserWithRoles();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID查询角色信息
|
||||||
|
*/
|
||||||
|
@Select("""
|
||||||
|
SELECT r.id, r.name ,r.code
|
||||||
|
FROM t_role r
|
||||||
|
JOIN t_user_role ur ON r.id = ur.role_id
|
||||||
|
WHERE ur.user_id = #{userId}
|
||||||
|
""")
|
||||||
|
List<Role> findRolesByUserId(@Param("userId") Long userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,10 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>mybatis-plus</artifactId>
|
<artifactId>mybatis-plus</artifactId>
|
||||||
@@ -29,5 +33,11 @@
|
|||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.validation</groupId>
|
||||||
|
<artifactId>jakarta.validation-api</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,21 +1,57 @@
|
|||||||
package cn.nopj.chaos_api.domain.entity;
|
package cn.nopj.chaos_api.domain.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@TableName("t_user")
|
@TableName("t_user")
|
||||||
public class User implements Serializable {
|
public class User implements Serializable {
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
private Long id;
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 用户名称
|
||||||
|
*/
|
||||||
private String username;
|
private String username;
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
private String password;
|
private String password;
|
||||||
|
/**
|
||||||
|
* 账号是否启用
|
||||||
|
*/
|
||||||
private Boolean enabled;
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 账号是否未过期
|
||||||
|
*/
|
||||||
private Boolean accountNonExpired;
|
private Boolean accountNonExpired;
|
||||||
|
/**
|
||||||
|
* 密码是否未过期
|
||||||
|
*/
|
||||||
private Boolean credentialsNonExpired;
|
private Boolean credentialsNonExpired;
|
||||||
|
/**
|
||||||
|
* 账号是否未锁定
|
||||||
|
*/
|
||||||
private Boolean accountNonLocked;
|
private Boolean accountNonLocked;
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
private LocalDateTime updateTime;
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<Role> roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package cn.nopj.chaos_api.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录请求参数
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class LoginRequest {
|
|
||||||
private String username;
|
|
||||||
private String password;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package cn.nopj.chaos_api.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注册请求参数
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class RegisterRequest {
|
|
||||||
private String username;
|
|
||||||
private String password;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package cn.nopj.chaos_api.dto.request;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录请求参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AuthLoginRequest {
|
||||||
|
@Pattern(regexp = "^[a-zA-Z0-9_-]{5,16}$", message = "用户名需为5-16位字母、数字、_或-")
|
||||||
|
private String username;
|
||||||
|
@Pattern(regexp = "^.{8,16}$", message = "密码长度需为8-16位")
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package cn.nopj.chaos_api.dto.request;
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册请求参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AuthRegisterRequest {
|
||||||
|
@Pattern(regexp = "^[a-zA-Z0-9_-]{5,16}$", message = "用户名需为5-16位字母、数字、_或-")
|
||||||
|
private String username;
|
||||||
|
//密码不低于8位 不高于16位不限制字符
|
||||||
|
@Pattern(regexp = "^.{8,16}$", message = "密码长度需为8-16位")
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package cn.nopj.chaos_api.dto.request;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SetUserPasswordRequest {
|
||||||
|
//用户id为数字Long类型
|
||||||
|
@Pattern(regexp = "^[0-9]+$", message = "用户id格式错误")
|
||||||
|
private String userId;
|
||||||
|
@Pattern(regexp = "^.{8,16}$", message = "密码长度需为8-16位")
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cn.nopj.chaos_api.dto;
|
package cn.nopj.chaos_api.dto.response;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package cn.nopj.chaos_api.dto.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
@Data
|
||||||
|
public class RoleResponse {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package cn.nopj.chaos_api.dto.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserinfoResponse {
|
||||||
|
private Long id;
|
||||||
|
private String username;
|
||||||
|
private List<RoleResponse> roles;
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package cn.nopj.chaos_api.service;
|
package cn.nopj.chaos_api.service;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.dto.response.FileUploadResponse;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
public interface ImageService {
|
public interface ImageService {
|
||||||
@@ -11,5 +13,5 @@ public interface ImageService {
|
|||||||
* @param content 文件内容
|
* @param content 文件内容
|
||||||
* @return 文件路径
|
* @return 文件路径
|
||||||
*/
|
*/
|
||||||
String uploadImage(String fileName, InputStream content);
|
FileUploadResponse uploadImage(String fileName, InputStream content);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package cn.nopj.chaos_api.service;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.dto.response.UserinfoResponse;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息服务
|
||||||
|
*
|
||||||
|
* @author nopj
|
||||||
|
*/
|
||||||
|
public interface UserInfoService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置用户密码
|
||||||
|
*
|
||||||
|
* @param id 用户id
|
||||||
|
* @param password 密码
|
||||||
|
*/
|
||||||
|
void setUserPassword(Long id, String password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有用户信息
|
||||||
|
*
|
||||||
|
* @return 所有用户信息
|
||||||
|
*/
|
||||||
|
List<UserinfoResponse> getAllUsers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置用户密码
|
||||||
|
*
|
||||||
|
* @param userId 用户id
|
||||||
|
* @param password 密码
|
||||||
|
*/
|
||||||
|
void setUserPassword(@Pattern(regexp = "^[0-9]+$", message = "用户id格式错误") String userId, @Pattern(regexp = "^.{8,16}$", message = "密码长度需为8-16位") String password);
|
||||||
|
}
|
||||||
@@ -50,5 +50,12 @@
|
|||||||
<artifactId>spring-web</artifactId>
|
<artifactId>spring-web</artifactId>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-crypto</artifactId>
|
||||||
|
<version>6.5.6</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.nopj.chaos_api.service.impl;
|
package cn.nopj.chaos_api.service.impl;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.dto.response.FileUploadResponse;
|
||||||
import cn.nopj.chaos_api.service.ImageService;
|
import cn.nopj.chaos_api.service.ImageService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -10,8 +11,8 @@ import java.io.InputStream;
|
|||||||
@Service
|
@Service
|
||||||
public class ImageServiceImpl implements ImageService {
|
public class ImageServiceImpl implements ImageService {
|
||||||
@Override
|
@Override
|
||||||
public String uploadImage(String fileName, InputStream content) {
|
public FileUploadResponse uploadImage(String fileName, InputStream content) {
|
||||||
//todo 完成上传图片功能
|
//todo 完成上传图片功能
|
||||||
return "";
|
return new FileUploadResponse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
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.RoleResponse;
|
||||||
|
import cn.nopj.chaos_api.dto.response.UserinfoResponse;
|
||||||
|
import cn.nopj.chaos_api.mapper.UserMapper;
|
||||||
|
import cn.nopj.chaos_api.service.UserInfoService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class UserInfoServiceImpl implements UserInfoService {
|
||||||
|
@Autowired
|
||||||
|
private PasswordEncoder passwordEncoder;
|
||||||
|
@Autowired
|
||||||
|
UserMapper userMapper;
|
||||||
|
@Override
|
||||||
|
public void setUserPassword(Long Id, String password) {
|
||||||
|
|
||||||
|
log.info("重置用户id: {}的密码", Id);
|
||||||
|
User user = userMapper.selectById(Id);
|
||||||
|
//查询用户是否存在
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
throw new BizException(ErrorCode.USER_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
user.setPassword(passwordEncoder.encode(password));
|
||||||
|
int i = userMapper.updateById(user);
|
||||||
|
log.info("重置用户id: {}的密码结果: {}", Id, i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserinfoResponse> getAllUsers() {
|
||||||
|
List<User> allUserWithRoles = userMapper.findAllUserWithRoles();
|
||||||
|
|
||||||
|
if (allUserWithRoles == null){
|
||||||
|
throw new RuntimeException("获取所有用户信息失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
return allUserWithRoles.stream().map(user -> {
|
||||||
|
UserinfoResponse userinfoResponse = new UserinfoResponse();
|
||||||
|
userinfoResponse.setId(user.getId());
|
||||||
|
userinfoResponse.setUsername(user.getUsername());
|
||||||
|
userinfoResponse.setRoles(
|
||||||
|
user.getRoles().stream().map(role -> {
|
||||||
|
RoleResponse roleResponse = new RoleResponse();
|
||||||
|
roleResponse.setId(role.getId());
|
||||||
|
roleResponse.setName(role.getName());
|
||||||
|
return roleResponse;
|
||||||
|
}).toList()
|
||||||
|
);
|
||||||
|
return userinfoResponse;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUserPassword(String userId, String password) {
|
||||||
|
try{
|
||||||
|
Long Id = Long.parseLong(userId);
|
||||||
|
setUserPassword(Id, password);
|
||||||
|
}catch (NumberFormatException e) {
|
||||||
|
throw new BizException(ErrorCode.USER_ID_INVALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -44,7 +44,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@@ -69,7 +68,6 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package cn.nopj.chaos_api;
|
package cn.nopj.chaos_api;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
@SpringBootApplication(scanBasePackages = "cn.nopj.chaos_api")
|
@SpringBootApplication(scanBasePackages = "cn.nopj.chaos_api")
|
||||||
|
@Slf4j
|
||||||
public class ChaosApiWebApplication {
|
public class ChaosApiWebApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(ChaosApiWebApplication.class, args);
|
SpringApplication.run(ChaosApiWebApplication.class, args);
|
||||||
|
|||||||
@@ -38,10 +38,8 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
|||||||
protected void doFilterInternal(HttpServletRequest request,
|
protected void doFilterInternal(HttpServletRequest request,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
FilterChain chain) throws ServletException, IOException {
|
FilterChain chain) throws ServletException, IOException {
|
||||||
log.info("JWT 登录授权过滤器");
|
|
||||||
|
|
||||||
String authHeader = request.getHeader(this.tokenHeader);
|
String authHeader = request.getHeader(this.tokenHeader);
|
||||||
log.info("authHeader: {}", authHeader);
|
|
||||||
if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
|
if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
|
||||||
String authToken = authHeader.substring(this.tokenHead.length()+1);
|
String authToken = authHeader.substring(this.tokenHead.length()+1);
|
||||||
log.info("authToken={}", authToken);
|
log.info("authToken={}", authToken);
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package cn.nopj.chaos_api.controller;
|
package cn.nopj.chaos_api.controller;
|
||||||
|
|
||||||
import cn.nopj.chaos_api.dto.LoginRequest;
|
import cn.nopj.chaos_api.converter.UserConverter;
|
||||||
import cn.nopj.chaos_api.dto.RegisterRequest;
|
import cn.nopj.chaos_api.dto.request.AuthLoginRequest;
|
||||||
|
import cn.nopj.chaos_api.dto.request.AuthRegisterRequest;
|
||||||
import cn.nopj.chaos_api.model.ApiResult;
|
import cn.nopj.chaos_api.model.ApiResult;
|
||||||
import cn.nopj.chaos_api.service.AuthService;
|
import cn.nopj.chaos_api.service.AuthService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.authentication.BadCredentialsException;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -15,6 +16,11 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证控管理
|
||||||
|
*
|
||||||
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/auth")
|
@RequestMapping("/api/auth")
|
||||||
public class AuthController {
|
public class AuthController {
|
||||||
@@ -24,38 +30,34 @@ public class AuthController {
|
|||||||
@Value("${jwt.tokenHead}")
|
@Value("${jwt.tokenHead}")
|
||||||
private String tokenHead;
|
private String tokenHead;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserConverter userConverter;
|
||||||
/**
|
/**
|
||||||
* 注册
|
* 注册
|
||||||
*
|
*
|
||||||
* @param registerRequest 注册信息
|
* @param authRegisterRequest 注册信息
|
||||||
* @return 注册结果
|
* @return 注册结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
public ApiResult<?> register(@RequestBody RegisterRequest registerRequest) {
|
public ApiResult<?> register(@Valid @RequestBody AuthRegisterRequest authRegisterRequest) {
|
||||||
if (authService.register(registerRequest) != null) {
|
return ApiResult.success(authService.register(userConverter.convert(authRegisterRequest)));
|
||||||
return ApiResult.success("注册成功");
|
|
||||||
}
|
|
||||||
return ApiResult.failed("用户名已存在");
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
*
|
*
|
||||||
* @param loginRequest 登录信息
|
* @param authLoginRequest 登录信息
|
||||||
* @return 登录结果
|
* @return 登录结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public ApiResult<?> login(@RequestBody LoginRequest loginRequest) {
|
public ApiResult<?> login(@RequestBody AuthLoginRequest authLoginRequest) {
|
||||||
try {
|
|
||||||
String token = authService.login(loginRequest.getUsername(), loginRequest.getPassword());
|
|
||||||
|
|
||||||
Map<String, String> tokenMap = new HashMap<>();
|
String token = authService.login(authLoginRequest.getUsername(), authLoginRequest.getPassword());
|
||||||
tokenMap.put("token", token);
|
|
||||||
tokenMap.put("tokenHead", tokenHead);
|
Map<String, String> tokenMap = new HashMap<>();
|
||||||
return ApiResult.success(tokenMap);
|
tokenMap.put("token", token);
|
||||||
|
tokenMap.put("tokenHead", tokenHead);
|
||||||
|
return ApiResult.success(tokenMap);
|
||||||
|
|
||||||
}catch (BadCredentialsException e){
|
|
||||||
return ApiResult.failed(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package cn.nopj.chaos_api.controller;
|
|
||||||
|
|
||||||
import cn.nopj.chaos_api.model.ApiResult;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/hls")
|
|
||||||
public class HLSController {
|
|
||||||
|
|
||||||
@PreAuthorize("hasAuthority('admin')")
|
|
||||||
@GetMapping("/")
|
|
||||||
ApiResult<String> getHLS(){
|
|
||||||
return ApiResult.success("HLS is radar");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.nopj.chaos_api.controller;
|
package cn.nopj.chaos_api.controller;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.dto.response.FileUploadResponse;
|
||||||
import cn.nopj.chaos_api.model.ApiResult;
|
import cn.nopj.chaos_api.model.ApiResult;
|
||||||
import cn.nopj.chaos_api.service.ImageService;
|
import cn.nopj.chaos_api.service.ImageService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -9,6 +10,12 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片管理
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/image")
|
@RequestMapping("/api/image")
|
||||||
@@ -16,9 +23,24 @@ public class ImageController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ImageService imageService;
|
private ImageService imageService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传图片
|
||||||
|
* @param file 文件
|
||||||
|
* @return 上传结果
|
||||||
|
*/
|
||||||
@RequestMapping("/upload")
|
@RequestMapping("/upload")
|
||||||
ApiResult<String> uploadImage(@RequestParam("file") MultipartFile file) {
|
ApiResult<String> uploadImage(@RequestParam("file") MultipartFile file) {
|
||||||
log.info("上传图片");
|
if (file.isEmpty()){
|
||||||
return ApiResult.success("上传成功");
|
return ApiResult.failed("上传文件不能为空");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String fileName = file.getName();
|
||||||
|
InputStream inputStream = file.getInputStream();
|
||||||
|
FileUploadResponse response = imageService.uploadImage(fileName, inputStream);
|
||||||
|
return ApiResult.success(response.getFileDownloadUri());
|
||||||
|
}catch (IOException e){
|
||||||
|
log.error("上传文件失败", e);
|
||||||
|
return ApiResult.failed("上传文件失败");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色管理
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
public class RoleController {
|
public class RoleController {
|
||||||
|
|||||||
@@ -1,13 +1,52 @@
|
|||||||
package cn.nopj.chaos_api.controller;
|
package cn.nopj.chaos_api.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.dto.request.SetUserPasswordRequest;
|
||||||
|
import cn.nopj.chaos_api.dto.response.UserinfoResponse;
|
||||||
|
import cn.nopj.chaos_api.model.ApiResult;
|
||||||
|
import cn.nopj.chaos_api.service.UserInfoService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户管理
|
||||||
|
*
|
||||||
|
* @author nopj
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
|
@RequestMapping("/api/user")
|
||||||
public class UserController {
|
public class UserController {
|
||||||
|
@Autowired
|
||||||
|
UserInfoService userInfoService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有用户信息
|
||||||
|
* @return 所有用户信息
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasAuthority('admin')")
|
||||||
|
@GetMapping("/all")
|
||||||
|
ApiResult<List<UserinfoResponse>> getAllUsers(){
|
||||||
|
return ApiResult.success(userInfoService.getAllUsers());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置用户密码
|
||||||
|
* @param request 设置用户密码请求
|
||||||
|
* @return 设置用户密码结果
|
||||||
|
*/
|
||||||
|
@PreAuthorize("hasAuthority('admin')")
|
||||||
|
@RequestMapping("/setUserPassword")
|
||||||
|
ApiResult<String> setUserPassword(@RequestBody SetUserPasswordRequest request){
|
||||||
|
userInfoService.setUserPassword(request.getUserId(), request.getPassword());
|
||||||
|
return ApiResult.success("用户密码修改成功");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package cn.nopj.chaos_api.exception;
|
||||||
|
|
||||||
|
import cn.nopj.chaos_api.common.exceotion.BizException;
|
||||||
|
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.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
|
public ApiResult<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||||
|
// 提取第一条错误提示
|
||||||
|
String errorMsg = Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage();
|
||||||
|
// 返回统一的错误格式
|
||||||
|
return ApiResult.failed(errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理自定义业务异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BizException.class)
|
||||||
|
public ApiResult<?> handleBizException(BizException ex) {
|
||||||
|
return ApiResult.failed(ex.getErrorCode().getHttpStatus(),ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兜底处理:处理所有未知的 RuntimeException
|
||||||
|
* 防止出现 500 错误页面,给前端返回友好的提示
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
public ApiResult<?> handleAllExceptions(Exception ex) {
|
||||||
|
log.error("服务器内部错误", ex);
|
||||||
|
return ApiResult.failed("服务器内部错误,请联系管理员");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
package cn.nopj.chaos_api.service;
|
package cn.nopj.chaos_api.service;
|
||||||
|
|
||||||
import cn.nopj.chaos_api.domain.entity.User;
|
import cn.nopj.chaos_api.domain.entity.User;
|
||||||
import cn.nopj.chaos_api.dto.RegisterRequest;
|
|
||||||
|
|
||||||
public interface AuthService {
|
public interface AuthService {
|
||||||
/**
|
/**
|
||||||
* 注册
|
* 注册
|
||||||
*/
|
*/
|
||||||
User register(RegisterRequest registerRequest);
|
User register(User user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package cn.nopj.chaos_api.service.impl;
|
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.domain.entity.User;
|
||||||
import cn.nopj.chaos_api.dto.RegisterRequest;
|
|
||||||
import cn.nopj.chaos_api.mapper.UserMapper;
|
import cn.nopj.chaos_api.mapper.UserMapper;
|
||||||
import cn.nopj.chaos_api.service.AuthService;
|
import cn.nopj.chaos_api.service.AuthService;
|
||||||
import cn.nopj.chaos_api.util.JwtTokenUtil;
|
import cn.nopj.chaos_api.util.JwtTokenUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
@@ -18,6 +18,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class AuthServiceImpl implements AuthService {
|
public class AuthServiceImpl implements AuthService {
|
||||||
|
|
||||||
|
|
||||||
@@ -31,35 +32,45 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User register(RegisterRequest registerRequest) {
|
public User register(User user) {
|
||||||
|
|
||||||
// 检查用户名是否已存在
|
// 检查用户名是否已存在
|
||||||
if (userMapper.selectOne(new QueryWrapper<User>().eq("username", registerRequest.getUsername())) != null) {
|
if (userMapper.selectByUsername(user.getUsername()) != null) {
|
||||||
// 在实际项目中,这里应该抛出自定义异常
|
// 在实际项目中,这里应该抛出自定义异常
|
||||||
return null;
|
throw new BizException(ErrorCode.USERNAME_EXISTS);
|
||||||
}
|
}
|
||||||
User user = new User();
|
|
||||||
user.setUsername(registerRequest.getUsername());
|
|
||||||
// 使用 BCrypt 加密密码
|
// 使用 BCrypt 加密密码
|
||||||
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
|
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||||
userMapper.insert(user);
|
userMapper.insert(user);
|
||||||
// 你可以在这里为新用户分配默认角色
|
// 你可以在这里为新用户分配默认角色
|
||||||
userMapper.insertUserRole(user.getId(), 2L);
|
userMapper.insertUserRole(user.getId(), 2L);
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String login(String username, String password) {
|
public String login(String username, String password) {
|
||||||
|
// 尝试进行身份验证
|
||||||
|
try{
|
||||||
Authentication authentication = authenticationManager.authenticate(
|
Authentication authentication = authenticationManager.authenticate(
|
||||||
new UsernamePasswordAuthenticationToken(username, password)
|
new UsernamePasswordAuthenticationToken(username, password)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 将认证结果保存在 SecurityContextHolder 中
|
||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
|
||||||
// 获取用户详情
|
// 获取用户详情
|
||||||
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
|
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
|
||||||
if (!userDetails.isEnabled()){
|
if (!userDetails.isEnabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// 生成 JWT
|
// 生成 JWT
|
||||||
return jwtTokenUtil.generateToken(userDetails);
|
return jwtTokenUtil.generateToken(userDetails);
|
||||||
|
}catch (Exception e){
|
||||||
|
|
||||||
|
throw new BizException(ErrorCode.USER_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
package cn.nopj.chaos_api.service.impl;
|
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.domain.entity.User;
|
||||||
import cn.nopj.chaos_api.mapper.UserMapper;
|
import cn.nopj.chaos_api.mapper.UserMapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -22,11 +23,11 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
UserMapper userMapper;
|
UserMapper userMapper;
|
||||||
@Override
|
@Override
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String username) {
|
||||||
// 1. 从数据库查询用户
|
// 1. 从数据库查询用户
|
||||||
User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
|
User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new UsernameNotFoundException("用户不存在");
|
throw new BizException(ErrorCode.USER_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 查询该用户的权限信息 (角色 + 权限)
|
// 2. 查询该用户的权限信息 (角色 + 权限)
|
||||||
@@ -38,6 +39,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
.map(SimpleGrantedAuthority::new)
|
.map(SimpleGrantedAuthority::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|
||||||
// 4. 构建并返回 Spring Security 的 User 对象
|
// 4. 构建并返回 Spring Security 的 User 对象
|
||||||
return new org.springframework.security.core.userdetails.User(
|
return new org.springframework.security.core.userdetails.User(
|
||||||
user.getUsername(),
|
user.getUsername(),
|
||||||
|
|||||||
13
pom.xml
13
pom.xml
@@ -119,6 +119,7 @@
|
|||||||
<artifactId>logback-classic</artifactId>
|
<artifactId>logback-classic</artifactId>
|
||||||
<version>1.5.18</version>
|
<version>1.5.18</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-amqp -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||||
@@ -130,6 +131,18 @@
|
|||||||
<artifactId>spring-web</artifactId>
|
<artifactId>spring-web</artifactId>
|
||||||
<version>6.2.13</version>
|
<version>6.2.13</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
<version>3.5.7</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>6.2.13</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
</project>
|
</project>
|
||||||
Reference in New Issue
Block a user