From dd329ec53b81c5307e6a1f029c337489b73922d1 Mon Sep 17 00:00:00 2001 From: XiaoLFeng Date: Sat, 30 Dec 2023 17:19:21 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=99=BB=E9=99=86=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aspect/TimestampAspect.java | 73 ++++++++++++++++++ .../resourcesdocking/common/util/.gitkeep | 0 .../common/util/ErrorCode.java | 20 +++-- .../common/util/Processing.java | 33 +++++++++ .../common/util/ResultUtil.java | 17 ++++- .../resourcesdocking/controllers/.gitkeep | 0 .../controllers/AuthController.java | 51 +++++++++++++ .../resourcesdocking/mappers/UserMapper.java | 20 +++++ .../function/resourcesdocking/model/.gitkeep | 0 .../resourcesdocking/model/entity/.gitkeep | 0 .../model/entity/AuthLoginEntity.java | 23 ++++++ .../repositories/AuthDAO.java | 74 +++++++++++++++++++ .../resourcesdocking/repository/.gitkeep | 0 .../resourcesdocking/services/.gitkeep | 0 .../services/AuthService.java | 25 +++++++ .../resourcesdocking/services/impl/.gitkeep | 0 .../services/impl/AuthServiceImpl.java | 61 +++++++++++++++ 17 files changed, 384 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/xlf/function/resourcesdocking/aspect/TimestampAspect.java delete mode 100644 src/main/java/org/xlf/function/resourcesdocking/common/util/.gitkeep create mode 100644 src/main/java/org/xlf/function/resourcesdocking/common/util/Processing.java delete mode 100644 src/main/java/org/xlf/function/resourcesdocking/controllers/.gitkeep create mode 100644 src/main/java/org/xlf/function/resourcesdocking/controllers/AuthController.java create mode 100644 src/main/java/org/xlf/function/resourcesdocking/mappers/UserMapper.java delete mode 100644 src/main/java/org/xlf/function/resourcesdocking/model/.gitkeep delete mode 100644 src/main/java/org/xlf/function/resourcesdocking/model/entity/.gitkeep create mode 100644 src/main/java/org/xlf/function/resourcesdocking/model/entity/AuthLoginEntity.java create mode 100644 src/main/java/org/xlf/function/resourcesdocking/repositories/AuthDAO.java delete mode 100644 src/main/java/org/xlf/function/resourcesdocking/repository/.gitkeep delete mode 100644 src/main/java/org/xlf/function/resourcesdocking/services/.gitkeep create mode 100644 src/main/java/org/xlf/function/resourcesdocking/services/AuthService.java delete mode 100644 src/main/java/org/xlf/function/resourcesdocking/services/impl/.gitkeep create mode 100644 src/main/java/org/xlf/function/resourcesdocking/services/impl/AuthServiceImpl.java diff --git a/src/main/java/org/xlf/function/resourcesdocking/aspect/TimestampAspect.java b/src/main/java/org/xlf/function/resourcesdocking/aspect/TimestampAspect.java new file mode 100644 index 0000000..be040c7 --- /dev/null +++ b/src/main/java/org/xlf/function/resourcesdocking/aspect/TimestampAspect.java @@ -0,0 +1,73 @@ +package org.xlf.function.resourcesdocking.aspect; + +import jakarta.servlet.http.HttpServletRequest; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.jetbrains.annotations.NotNull; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.xlf.function.resourcesdocking.common.util.ErrorCode; +import org.xlf.function.resourcesdocking.common.util.ResultUtil; + +import java.util.Objects; + +/** + *

TimestampAspect 时间戳切面

+ *
+ * 用于处理时间戳相关逻辑 + * + * @since v1.0.0 + * @version v1.0.0 + */ +@Aspect +@Component +public class TimestampAspect { + /** + *

authControllerAround 认证控制器切面

+ *
+ * 用于认证控制器的切面 + * + * @param pjp ProceedingJoinPoint对象 + * @return {@link Object} + */ + @Around("execution(* org.xlf.function.resourcesdocking.controllers.AuthController.*(..))") + public Object authControllerAround(ProceedingJoinPoint pjp) throws Throwable { + // 获取HttpServletRequest对象 + HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); + + // 时间戳检查 + if (checkTimestamp(request)) { + // TODO: 2023/12/30 0001 后期固定业务(如:日志处理) + return pjp.proceed(); + } else { + return ResultUtil.error(ErrorCode.TIMESTAMP_IS_NOT_IN_TIME); + } + } + + /** + *

checkTimestamp 检查时间戳

+ *
+ * 用于检查时间戳是否合法,合法时间范围正负 1 秒 + * + * @param request HttpServletRequest对象 + * @return {@link Boolean} + */ + public Boolean checkTimestamp(@NotNull HttpServletRequest request) { + // 获取请求头中的时间戳 + String getTimestamp = request.getHeader("Timestamp"); + // 判断是否为空 + if (getTimestamp == null || getTimestamp.isEmpty()) { + return false; + } else { + if (getTimestamp.length() == 10) { + getTimestamp += "000"; + } + } + // 获取当前时间戳 + long nowTimestamp = System.currentTimeMillis(); + // 时间误差允许前后五秒钟 + return nowTimestamp - Long.parseLong(getTimestamp) <= 1000 && nowTimestamp - Long.parseLong(getTimestamp) >= -1000; + } +} diff --git a/src/main/java/org/xlf/function/resourcesdocking/common/util/.gitkeep b/src/main/java/org/xlf/function/resourcesdocking/common/util/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/org/xlf/function/resourcesdocking/common/util/ErrorCode.java b/src/main/java/org/xlf/function/resourcesdocking/common/util/ErrorCode.java index 8e6fc96..a576d54 100644 --- a/src/main/java/org/xlf/function/resourcesdocking/common/util/ErrorCode.java +++ b/src/main/java/org/xlf/function/resourcesdocking/common/util/ErrorCode.java @@ -1,8 +1,10 @@ package org.xlf.function.resourcesdocking.common.util; import lombok.Getter; +import lombok.RequiredArgsConstructor; @Getter +@RequiredArgsConstructor public enum ErrorCode { /* @@ -11,19 +13,15 @@ public enum ErrorCode { WRONG_PASSWORD("WrongPassword", 40000, "密码错误"), USER_NOT_FOUND("UserNotFound", 40001, "用户不存在"), USER_EXIST("UserExist", 40002, "用户已存在"), - USER_BAN("UserBan", 40003, "用户已被封禁"), - USER_VERIFY("UserVerify", 40004, "用户未通过验证"), - USER_NOT_LOGIN("UserNotLogin", 40005, "用户未登录"), - USER_NOT_PERMISSION("UserNotPermission", 40006, "用户无权限"), - USER_NOT_ACTIVE("UserNotActive", 40007, "用户未激活"); + REQUEST_BODY_ERROR("RequestBodyError", 40003, "请求体错误"), + USER_VERIFY("UserVerify", 40100, "用户未通过验证"), + USER_BAN("UserBan", 40101, "用户已被封禁"), + USER_NOT_LOGIN("UserNotLogin", 40102, "用户未登录"), + USER_NOT_PERMISSION("UserNotPermission", 40103, "用户无权限"), + USER_NOT_ACTIVE("UserNotActive", 40104, "用户未激活"), + TIMESTAMP_IS_NOT_IN_TIME("TimestampIsNotInTime", 40300, "时间戳不在合法时间内"); private final String output; private final Integer code; private final String message; - - ErrorCode(String output, Integer code, String message) { - this.output = output; - this.code = code; - this.message = message; - } } diff --git a/src/main/java/org/xlf/function/resourcesdocking/common/util/Processing.java b/src/main/java/org/xlf/function/resourcesdocking/common/util/Processing.java new file mode 100644 index 0000000..73ea1dc --- /dev/null +++ b/src/main/java/org/xlf/function/resourcesdocking/common/util/Processing.java @@ -0,0 +1,33 @@ +package org.xlf.function.resourcesdocking.common.util; + +import org.jetbrains.annotations.NotNull; +import org.springframework.validation.BindingResult; +import org.springframework.validation.ObjectError; + +import java.util.ArrayList; + +/** + *

Processing 处理工具类

+ *
+ * 用于处理数据 + * + * @version v1.0.0 + * @since v1.0.0 + */ +public class Processing { + /** + *

getValidatedErrorList 获取验证错误信息列表

+ *
+ * 用于获取验证错误信息列表 + * + * @param bindingResult 错误信息 + * @return {@link ArrayList} + */ + public static @NotNull ArrayList getValidatedErrorList(BindingResult bindingResult) { + ArrayList arrayList = new ArrayList<>(); + for (ObjectError objectError : bindingResult.getAllErrors()) { + arrayList.add(objectError.getDefaultMessage()); + } + return arrayList; + } +} diff --git a/src/main/java/org/xlf/function/resourcesdocking/common/util/ResultUtil.java b/src/main/java/org/xlf/function/resourcesdocking/common/util/ResultUtil.java index cc9530e..cf10ed0 100644 --- a/src/main/java/org/xlf/function/resourcesdocking/common/util/ResultUtil.java +++ b/src/main/java/org/xlf/function/resourcesdocking/common/util/ResultUtil.java @@ -76,6 +76,19 @@ public class ResultUtil { return new BaseResponse(errorCode.getOutput(), errorCode.getCode(), errorCode.getMessage()); } + /** + *

Error 错误响应结果

+ *
+ * 用于封装错误响应结果 + * + * @param errorCode 错误码 + * @param data 响应数据 + * @return BaseResponse + */ + public static @NotNull BaseResponse error(@NotNull ErrorCode errorCode, Object data) { + return new BaseResponse(errorCode.getOutput(), errorCode.getCode(), errorCode.getMessage(), data); + } + /** *

Error 错误响应结果

*
@@ -86,7 +99,7 @@ public class ResultUtil { * @param message 响应信息 * @return BaseResponse */ - public static @NotNull BaseResponse error(String output, Integer code, String message) { - return new BaseResponse(output, code, message); + public static @NotNull BaseResponse error(String output, Integer code, String message, Object data) { + return new BaseResponse(output, code, message, data); } } diff --git a/src/main/java/org/xlf/function/resourcesdocking/controllers/.gitkeep b/src/main/java/org/xlf/function/resourcesdocking/controllers/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/org/xlf/function/resourcesdocking/controllers/AuthController.java b/src/main/java/org/xlf/function/resourcesdocking/controllers/AuthController.java new file mode 100644 index 0000000..1960b69 --- /dev/null +++ b/src/main/java/org/xlf/function/resourcesdocking/controllers/AuthController.java @@ -0,0 +1,51 @@ +package org.xlf.function.resourcesdocking.controllers; + +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.springframework.validation.BindingResult; +import org.springframework.validation.annotation.Validated; +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.xlf.function.resourcesdocking.common.util.BaseResponse; +import org.xlf.function.resourcesdocking.common.util.ErrorCode; +import org.xlf.function.resourcesdocking.common.util.Processing; +import org.xlf.function.resourcesdocking.common.util.ResultUtil; +import org.xlf.function.resourcesdocking.model.entity.AuthLoginEntity; +import org.xlf.function.resourcesdocking.services.AuthService; + +/** + *

AuthController 认证控制器

+ *
+ * 用于处理认证相关请求 + * + * @version v1.0.0 + * @since v1.0.0 + */ +@RestController +@RequestMapping("/user") +@RequiredArgsConstructor +public class AuthController { + /** + * 认证服务 + */ + private final AuthService authService; + + /** + *

userSignIn 用户登录

+ *
+ * 用于处理用户登录请求 + * + * @return BaseResponse + */ + @GetMapping("/sign/in") + public BaseResponse userSignIn(@RequestBody @Validated AuthLoginEntity loginEntity, @NotNull BindingResult bindingResult) { + // 验证请求体 + if (bindingResult.hasErrors()) { + return ResultUtil.error(ErrorCode.REQUEST_BODY_ERROR, Processing.getValidatedErrorList(bindingResult)); + } + // 处理用户登录 + return authService.userSignIn(loginEntity); + } +} diff --git a/src/main/java/org/xlf/function/resourcesdocking/mappers/UserMapper.java b/src/main/java/org/xlf/function/resourcesdocking/mappers/UserMapper.java new file mode 100644 index 0000000..32c526b --- /dev/null +++ b/src/main/java/org/xlf/function/resourcesdocking/mappers/UserMapper.java @@ -0,0 +1,20 @@ +package org.xlf.function.resourcesdocking.mappers; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +import org.xlf.function.resourcesdocking.model.UserDO; + +@Mapper +public interface UserMapper { + @Select("SELECT * FROM srd_user WHERE username = #{username} LIMIT 1") + UserDO getUserByUsername(String username); + + @Select("SELECT * FROM srd_user WHERE email = #{email} LIMIT 1") + UserDO getUserByEmail(String email); + + @Select("SELECT * FROM srd_user WHERE id = #{id} LIMIT 1") + UserDO getUserById(Long id); + + @Select("SELECT * FROM srd_user WHERE tel_country_area = #{country} AND tel = #{tel} LIMIT 1") + UserDO getUserByTelephone(String country, String tel); +} diff --git a/src/main/java/org/xlf/function/resourcesdocking/model/.gitkeep b/src/main/java/org/xlf/function/resourcesdocking/model/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/org/xlf/function/resourcesdocking/model/entity/.gitkeep b/src/main/java/org/xlf/function/resourcesdocking/model/entity/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/org/xlf/function/resourcesdocking/model/entity/AuthLoginEntity.java b/src/main/java/org/xlf/function/resourcesdocking/model/entity/AuthLoginEntity.java new file mode 100644 index 0000000..76d42b2 --- /dev/null +++ b/src/main/java/org/xlf/function/resourcesdocking/model/entity/AuthLoginEntity.java @@ -0,0 +1,23 @@ +package org.xlf.function.resourcesdocking.model.entity; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +/** + *

AuthLoginEntity 登录实体类

+ *
+ * 用于封装登录信息 + * + * @since v1.0.0 + * @version v1.0.0 + * @author 筱锋xiao_lfeng + */ +@Getter +@Setter +public class AuthLoginEntity { + @NotBlank(message = "用户名不能为空") + private String user; + @NotBlank(message = "密码不能为空") + private String password; +} diff --git a/src/main/java/org/xlf/function/resourcesdocking/repositories/AuthDAO.java b/src/main/java/org/xlf/function/resourcesdocking/repositories/AuthDAO.java new file mode 100644 index 0000000..027f2c3 --- /dev/null +++ b/src/main/java/org/xlf/function/resourcesdocking/repositories/AuthDAO.java @@ -0,0 +1,74 @@ +package org.xlf.function.resourcesdocking.repositories; + +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.springframework.stereotype.Repository; +import org.xlf.function.resourcesdocking.mappers.UserMapper; +import org.xlf.function.resourcesdocking.model.UserDO; + +/** + *

AuthDAO 认证数据访问对象

+ *
+ * 用于访问认证相关数据 + * + * @since v1.0.0 + * @version v1.0.0 + */ +@Repository +@RequiredArgsConstructor +public class AuthDAO { + /** + *

userMapper 用户映射器

+ *
+ * 用于访问用户相关数据 + */ + private final UserMapper userMapper; + + /** + *

getUserByUsername 根据用户名获取用户信息

+ *
+ * 用于根据用户名获取用户信息 + * + * @param username 用户名 + * @return {@link UserDO} + */ + public UserDO getUserByUsername(String username) { + return userMapper.getUserByUsername(username); + } + + /** + *

getUserByEmail 根据邮箱获取用户信息

+ *
+ * 用于根据邮箱获取用户信息 + * + * @param email 邮箱 + * @return {@link UserDO} + */ + public UserDO getUserByEmail(String email) { + return userMapper.getUserByEmail(email); + } + + /** + *

getUserById 根据用户 ID 获取用户信息

+ *
+ * 用于根据用户 ID 获取用户信息 + * + * @param id 用户 ID + * @return {@link UserDO} + */ + public UserDO getUserById(Long id) { + return userMapper.getUserById(id); + } + + /** + *

getUserByTelephone 根据手机号获取用户信息

+ *
+ * 用于根据手机号获取用户信息 + * + * @param tel 手机号 + * @return {@link UserDO} + */ + public UserDO getUserByTelephone(String @NotNull [] tel) { + return userMapper.getUserByTelephone(tel[0], tel[1]); + } +} diff --git a/src/main/java/org/xlf/function/resourcesdocking/repository/.gitkeep b/src/main/java/org/xlf/function/resourcesdocking/repository/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/org/xlf/function/resourcesdocking/services/.gitkeep b/src/main/java/org/xlf/function/resourcesdocking/services/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/org/xlf/function/resourcesdocking/services/AuthService.java b/src/main/java/org/xlf/function/resourcesdocking/services/AuthService.java new file mode 100644 index 0000000..e18c035 --- /dev/null +++ b/src/main/java/org/xlf/function/resourcesdocking/services/AuthService.java @@ -0,0 +1,25 @@ +package org.xlf.function.resourcesdocking.services; + +import org.xlf.function.resourcesdocking.common.util.BaseResponse; +import org.xlf.function.resourcesdocking.model.entity.AuthLoginEntity; + +/** + *

AuthService 认证服务接口

+ *
+ * 用于处理认证相关请求 + * + * @version v1.0.0 + * @see org.xlf.function.resourcesdocking.services.impl.AuthServiceImpl + * @since v1.0.0 + */ +public interface AuthService { + /** + *

userSignIn 用户登录

+ *
+ * 用于处理用户登录请求 + * + * @param loginEntity 登录实体 + * @return BaseResponse + */ + BaseResponse userSignIn(AuthLoginEntity loginEntity); +} diff --git a/src/main/java/org/xlf/function/resourcesdocking/services/impl/.gitkeep b/src/main/java/org/xlf/function/resourcesdocking/services/impl/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/org/xlf/function/resourcesdocking/services/impl/AuthServiceImpl.java b/src/main/java/org/xlf/function/resourcesdocking/services/impl/AuthServiceImpl.java new file mode 100644 index 0000000..c9aa54f --- /dev/null +++ b/src/main/java/org/xlf/function/resourcesdocking/services/impl/AuthServiceImpl.java @@ -0,0 +1,61 @@ +package org.xlf.function.resourcesdocking.services.impl; + +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.mindrot.jbcrypt.BCrypt; +import org.springframework.stereotype.Service; +import org.xlf.function.resourcesdocking.common.util.BaseResponse; +import org.xlf.function.resourcesdocking.common.util.ErrorCode; +import org.xlf.function.resourcesdocking.common.util.ResultUtil; +import org.xlf.function.resourcesdocking.model.UserDO; +import org.xlf.function.resourcesdocking.model.entity.AuthLoginEntity; +import org.xlf.function.resourcesdocking.repositories.AuthDAO; +import org.xlf.function.resourcesdocking.services.AuthService; + +import java.util.ArrayList; +import java.util.regex.Pattern; + +/** + *

AuthServiceImpl 认证服务实现类

+ *
+ * 用于处理认证相关请求 + * + * @since v1.0.0 + * @version v1.0.0 + */ +@Service +@RequiredArgsConstructor +public class AuthServiceImpl implements AuthService { + /** + * 认证数据访问对象 + */ + private final AuthDAO authDAO; + + @Override + public BaseResponse userSignIn(@NotNull AuthLoginEntity loginEntity) { + // 正则表达式检查用户数据 + UserDO userDO; + if (Pattern.matches("^[a-zA-Z0-9_-]{3,40}$", loginEntity.getUser())) { + userDO = authDAO.getUserByUsername(loginEntity.getUser()); + } else if (Pattern.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", loginEntity.getUser())) { + userDO = authDAO.getUserByEmail(loginEntity.getUser()); + } else if (Pattern.matches("^\\+[0-9]+ [0-9]+$", loginEntity.getUser())) { + // 拆分国区与手机号 + String[] split = loginEntity.getUser().split(" "); + split[0] = new StringBuilder(split[0]).deleteCharAt(0).toString(); + userDO = authDAO.getUserByTelephone(split); + } else { + return ResultUtil.error(ErrorCode.REQUEST_BODY_ERROR, new ArrayList().add("用户名或邮箱或手机号格式错误")); + } + // 验证用户是否存在 + if (userDO == null) { + return ResultUtil.error(ErrorCode.USER_NOT_FOUND); + } + // 验证密码是否正确 + if (BCrypt.checkpw(loginEntity.getPassword(), userDO.getPassword())) { + return ResultUtil.success("Success", "登陆成功",userDO); + } else { + return ResultUtil.error(ErrorCode.WRONG_PASSWORD); + } + } +}