用户登陆模块
This commit is contained in:
parent
cc96bfe7fc
commit
dd329ec53b
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>TimestampAspect 时间戳切面</h1>
|
||||||
|
* <hr/>
|
||||||
|
* 用于处理时间戳相关逻辑
|
||||||
|
*
|
||||||
|
* @since v1.0.0
|
||||||
|
* @version v1.0.0
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class TimestampAspect {
|
||||||
|
/**
|
||||||
|
* <h2>authControllerAround 认证控制器切面</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于认证控制器的切面
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>checkTimestamp 检查时间戳</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于检查时间戳是否合法,合法时间范围正负 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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
package org.xlf.function.resourcesdocking.common.util;
|
package org.xlf.function.resourcesdocking.common.util;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
public enum ErrorCode {
|
public enum ErrorCode {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -11,19 +13,15 @@ public enum ErrorCode {
|
|||||||
WRONG_PASSWORD("WrongPassword", 40000, "密码错误"),
|
WRONG_PASSWORD("WrongPassword", 40000, "密码错误"),
|
||||||
USER_NOT_FOUND("UserNotFound", 40001, "用户不存在"),
|
USER_NOT_FOUND("UserNotFound", 40001, "用户不存在"),
|
||||||
USER_EXIST("UserExist", 40002, "用户已存在"),
|
USER_EXIST("UserExist", 40002, "用户已存在"),
|
||||||
USER_BAN("UserBan", 40003, "用户已被封禁"),
|
REQUEST_BODY_ERROR("RequestBodyError", 40003, "请求体错误"),
|
||||||
USER_VERIFY("UserVerify", 40004, "用户未通过验证"),
|
USER_VERIFY("UserVerify", 40100, "用户未通过验证"),
|
||||||
USER_NOT_LOGIN("UserNotLogin", 40005, "用户未登录"),
|
USER_BAN("UserBan", 40101, "用户已被封禁"),
|
||||||
USER_NOT_PERMISSION("UserNotPermission", 40006, "用户无权限"),
|
USER_NOT_LOGIN("UserNotLogin", 40102, "用户未登录"),
|
||||||
USER_NOT_ACTIVE("UserNotActive", 40007, "用户未激活");
|
USER_NOT_PERMISSION("UserNotPermission", 40103, "用户无权限"),
|
||||||
|
USER_NOT_ACTIVE("UserNotActive", 40104, "用户未激活"),
|
||||||
|
TIMESTAMP_IS_NOT_IN_TIME("TimestampIsNotInTime", 40300, "时间戳不在合法时间内");
|
||||||
|
|
||||||
private final String output;
|
private final String output;
|
||||||
private final Integer code;
|
private final Integer code;
|
||||||
private final String message;
|
private final String message;
|
||||||
|
|
||||||
ErrorCode(String output, Integer code, String message) {
|
|
||||||
this.output = output;
|
|
||||||
this.code = code;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>Processing 处理工具类</h1>
|
||||||
|
* <hr/>
|
||||||
|
* 用于处理数据
|
||||||
|
*
|
||||||
|
* @version v1.0.0
|
||||||
|
* @since v1.0.0
|
||||||
|
*/
|
||||||
|
public class Processing {
|
||||||
|
/**
|
||||||
|
* <h2>getValidatedErrorList 获取验证错误信息列表</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于获取验证错误信息列表
|
||||||
|
*
|
||||||
|
* @param bindingResult 错误信息
|
||||||
|
* @return {@link ArrayList<String>}
|
||||||
|
*/
|
||||||
|
public static @NotNull ArrayList<String> getValidatedErrorList(BindingResult bindingResult) {
|
||||||
|
ArrayList<String> arrayList = new ArrayList<>();
|
||||||
|
for (ObjectError objectError : bindingResult.getAllErrors()) {
|
||||||
|
arrayList.add(objectError.getDefaultMessage());
|
||||||
|
}
|
||||||
|
return arrayList;
|
||||||
|
}
|
||||||
|
}
|
@ -76,6 +76,19 @@ public class ResultUtil {
|
|||||||
return new BaseResponse(errorCode.getOutput(), errorCode.getCode(), errorCode.getMessage());
|
return new BaseResponse(errorCode.getOutput(), errorCode.getCode(), errorCode.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>Error 错误响应结果</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于封装错误响应结果
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <h2>Error 错误响应结果</h2>
|
* <h2>Error 错误响应结果</h2>
|
||||||
* <hr/>
|
* <hr/>
|
||||||
@ -86,7 +99,7 @@ public class ResultUtil {
|
|||||||
* @param message 响应信息
|
* @param message 响应信息
|
||||||
* @return BaseResponse
|
* @return BaseResponse
|
||||||
*/
|
*/
|
||||||
public static @NotNull BaseResponse error(String output, Integer code, String message) {
|
public static @NotNull BaseResponse error(String output, Integer code, String message, Object data) {
|
||||||
return new BaseResponse(output, code, message);
|
return new BaseResponse(output, code, message, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>AuthController 认证控制器</h1>
|
||||||
|
* <hr/>
|
||||||
|
* 用于处理认证相关请求
|
||||||
|
*
|
||||||
|
* @version v1.0.0
|
||||||
|
* @since v1.0.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/user")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AuthController {
|
||||||
|
/**
|
||||||
|
* 认证服务
|
||||||
|
*/
|
||||||
|
private final AuthService authService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>userSignIn 用户登录</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于处理用户登录请求
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.xlf.function.resourcesdocking.model.entity;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>AuthLoginEntity 登录实体类</h1>
|
||||||
|
* <hr/>
|
||||||
|
* 用于封装登录信息
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>AuthDAO 认证数据访问对象</h1>
|
||||||
|
* <hr/>
|
||||||
|
* 用于访问认证相关数据
|
||||||
|
*
|
||||||
|
* @since v1.0.0
|
||||||
|
* @version v1.0.0
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AuthDAO {
|
||||||
|
/**
|
||||||
|
* <h2>userMapper 用户映射器</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于访问用户相关数据
|
||||||
|
*/
|
||||||
|
private final UserMapper userMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>getUserByUsername 根据用户名获取用户信息</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于根据用户名获取用户信息
|
||||||
|
*
|
||||||
|
* @param username 用户名
|
||||||
|
* @return {@link UserDO}
|
||||||
|
*/
|
||||||
|
public UserDO getUserByUsername(String username) {
|
||||||
|
return userMapper.getUserByUsername(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>getUserByEmail 根据邮箱获取用户信息</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于根据邮箱获取用户信息
|
||||||
|
*
|
||||||
|
* @param email 邮箱
|
||||||
|
* @return {@link UserDO}
|
||||||
|
*/
|
||||||
|
public UserDO getUserByEmail(String email) {
|
||||||
|
return userMapper.getUserByEmail(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>getUserById 根据用户 ID 获取用户信息</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于根据用户 ID 获取用户信息
|
||||||
|
*
|
||||||
|
* @param id 用户 ID
|
||||||
|
* @return {@link UserDO}
|
||||||
|
*/
|
||||||
|
public UserDO getUserById(Long id) {
|
||||||
|
return userMapper.getUserById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>getUserByTelephone 根据手机号获取用户信息</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于根据手机号获取用户信息
|
||||||
|
*
|
||||||
|
* @param tel 手机号
|
||||||
|
* @return {@link UserDO}
|
||||||
|
*/
|
||||||
|
public UserDO getUserByTelephone(String @NotNull [] tel) {
|
||||||
|
return userMapper.getUserByTelephone(tel[0], tel[1]);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>AuthService 认证服务接口</h1>
|
||||||
|
* <hr/>
|
||||||
|
* 用于处理认证相关请求
|
||||||
|
*
|
||||||
|
* @version v1.0.0
|
||||||
|
* @see org.xlf.function.resourcesdocking.services.impl.AuthServiceImpl
|
||||||
|
* @since v1.0.0
|
||||||
|
*/
|
||||||
|
public interface AuthService {
|
||||||
|
/**
|
||||||
|
* <h2>userSignIn 用户登录</h2>
|
||||||
|
* <hr/>
|
||||||
|
* 用于处理用户登录请求
|
||||||
|
*
|
||||||
|
* @param loginEntity 登录实体
|
||||||
|
* @return BaseResponse
|
||||||
|
*/
|
||||||
|
BaseResponse userSignIn(AuthLoginEntity loginEntity);
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>AuthServiceImpl 认证服务实现类</h1>
|
||||||
|
* <hr/>
|
||||||
|
* 用于处理认证相关请求
|
||||||
|
*
|
||||||
|
* @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<String>().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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user