用户登出,修改密码。系统测试,添加日志

This commit is contained in:
筱锋xiao_lfeng 2024-01-18 00:52:24 +08:00
parent 2d541308e5
commit abd725d238
Signed by: XiaoLFeng
GPG Key ID: F693AA12AABBFA87
23 changed files with 360 additions and 90 deletions

1
.gitignore vendored
View File

@ -35,3 +35,4 @@ build/
### 自定义 ###
*.pdf
/src/main/resources/application-dev.yml
/src/main/resources/application-test.yml

View File

@ -15,6 +15,7 @@
<description>JSL_OrganizeInternalOA</description>
<properties>
<java.version>1.8</java.version>
<skipTests>true</skipTests>
</properties>
<dependencies>
<dependency>

View File

@ -1,7 +1,10 @@
package com.jsl.oa.aspect;
import com.jsl.oa.common.constant.BusinessConstants;
import com.jsl.oa.utils.ErrorCode;
import com.jsl.oa.utils.ResultUtil;
import com.jsl.oa.utils.redis.TokenRedisUtil;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@ -18,23 +21,25 @@ import java.util.Objects;
* <hr/>
* 用于用户控制器的切面
*
* @since v1.0.0
* @version v1.0.0
* @author 筱锋xiao_lfeng
* @version v1.0.0
* @since v1.0.0
*/
@Aspect
@Component
public class UserControllerAspect {
@RequiredArgsConstructor
public class AuthControllerAspect {
private final TokenRedisUtil<String> tokenRedisUtil;
/**
* <h1>用户控制器切面</h1>
* <hr/>
* 用于用户控制器的切面
*
* @since v1.0.0
* @param pjp ProceedingJoinPoint对象
* @return {@link Object}
* @throws Throwable 异常
* @since v1.0.0
*/
@Around("execution(* com.jsl.oa.controllers.AuthController.*(..))")
public Object controllerAround(ProceedingJoinPoint pjp) throws Throwable {
@ -51,14 +56,33 @@ public class UserControllerAspect {
}
@Around("execution(* com.jsl.oa.controllers.AuthController.authLogout(..)) || execution(* com.jsl.oa.controllers.AuthController.authChangePassword(..))")
public Object tokenControllerAround(ProceedingJoinPoint pjp) throws Throwable {
// 获取 HttpServletRequest 对象
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
// 检查 Token 是否有效
String token = request.getHeader("Authorization");
if (token != null && !token.isEmpty()) {
// 获取 Redis 检查 Token 是否存在
String finalToken = token.replace("Bearer ", "");
for (String it : tokenRedisUtil.getList(BusinessConstants.BUSINESS_LOGIN)) {
if (it.equals(finalToken)) {
return pjp.proceed();
}
}
}
return ResultUtil.error(ErrorCode.TOKEN_NOT_EXIST);
}
/**
* <h1>时间戳检查</h1>
* <hr/>
* 用于检查时间戳是否合法合法时间范围正负5秒
*
* @since v1.0.0
* @param request HttpServletRequest对象
* @return {@link Boolean}
* @since v1.0.0
*/
public Boolean checkTimestamp(@NotNull HttpServletRequest request) {
// 获取请求头中的时间戳

View File

@ -7,7 +7,8 @@ import lombok.Getter;
*/
@Getter
public enum BusinessConstants {
BUSINESS_LOGIN("login:", "登陆实现");
BUSINESS_LOGIN("login:", "登陆实现"),
NONE("", "null");
private final String value;
private final String description;

View File

@ -17,9 +17,11 @@ public class RedisConstant {
* 类型分类
*/
public static final String TYPE_EMAIL = "mail:"; // 邮件相关
public static final String TYPE_AUTH = "auth:"; // 登陆相关
/*
* 表分类
*/
public static final String TABLE_EMAIL = "code:"; // 邮箱验证码
public static final String TABLE_TOKEN = "token:"; // 令牌相关
}

View File

@ -41,7 +41,6 @@ public class JwtFilter extends BasicHttpAuthenticationFilter {
} else {
// 解析Bearer后面的令牌
token = token.replace("Bearer ", "");
System.out.println(token);
return JwtUtil.verify(token);
}
}

View File

@ -5,6 +5,8 @@ import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor
@ -56,4 +58,23 @@ public abstract class RedisOperating<R> {
redisTemplate.opsForValue().set(key, value);
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
/**
* <h2>基础从Redis获取List</h2>
* <hr/>
* 基础方法用于从Redis获取List<br/>
*
* @param pattern 正则表达式
* @return 返回List
*/
public List<R> getList(String pattern) {
// 获取全部匹配的key
Set<String> keys = stringRedisTemplate.keys(pattern);
// 获取全部匹配的value
if (keys != null) {
return redisTemplate.opsForValue().multiGet(keys);
} else {
return null;
}
}
}

View File

@ -1,5 +1,6 @@
package com.jsl.oa.controllers;
import com.jsl.oa.model.voData.UserChangePasswordVO;
import com.jsl.oa.model.voData.UserLoginVO;
import com.jsl.oa.model.voData.UserRegisterVO;
import com.jsl.oa.services.AuthService;
@ -13,7 +14,7 @@ import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern;
/**
@ -46,7 +47,7 @@ public class AuthController {
* @since v1.0.0
*/
@PostMapping("/auth/register")
public BaseResponse authRegister(@RequestBody @Validated UserRegisterVO userRegisterVO, @NotNull BindingResult bindingResult) throws ParseException {
public BaseResponse authRegister(@RequestBody @Validated UserRegisterVO userRegisterVO, @NotNull BindingResult bindingResult) {
// 判断是否有参数错误
if (bindingResult.hasErrors()) {
return ResultUtil.error(ErrorCode.REQUEST_BODY_ERROR, Processing.getValidatedErrorList(bindingResult));
@ -98,10 +99,16 @@ public class AuthController {
}
@GetMapping("/auth/login/email")
public BaseResponse authLoginByEmail(@RequestParam String email, @RequestParam Integer code) {
if (email != null && code != null) {
public BaseResponse authLoginByEmail(@RequestParam String email, @RequestParam String code) {
if (email != null && code != null && !email.isEmpty() && !code.isEmpty()) {
System.out.println("测试");
if (Pattern.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", email)) {
return authService.authLoginByEmail(email, code);
try {
Integer integer = Integer.valueOf(code);
return authService.authLoginByEmail(email, integer);
} catch (NumberFormatException e) {
return ResultUtil.error(ErrorCode.VERIFICATION_INVALID);
}
} else {
return ResultUtil.error(ErrorCode.PARAMETER_ERROR);
}
@ -119,7 +126,15 @@ public class AuthController {
* @since v1.1.0
*/
@GetMapping("/auth/logout")
public BaseResponse authLogout() {
return null;
public BaseResponse authLogout(HttpServletRequest request) {
return authService.authLogout(request);
}
@GetMapping("/auth/password")
public BaseResponse authChangePassword(@RequestBody @Validated UserChangePasswordVO userChangePasswordVO, HttpServletRequest request, @NotNull BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return ResultUtil.error(ErrorCode.REQUEST_BODY_ERROR, Processing.getValidatedErrorList(bindingResult));
}
return authService.authChangePassword(request, userChangePasswordVO);
}
}

View File

@ -1,25 +1,14 @@
package com.jsl.oa.controllers;
import com.jsl.oa.services.MailService;
import com.jsl.oa.utils.BaseResponse;
import com.jsl.oa.utils.ResultUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class CustomController implements ErrorController {
private final MailService mailService;
@RequestMapping("/")
public BaseResponse index() {
return ResultUtil.success("欢迎使用JSL-OA系统服务器处于正常状态");
}
@RequestMapping("/error")
public ResponseEntity<BaseResponse> handleError() {
return ResultUtil.error("PageNotFound", 404, "请求资源不存在");

View File

@ -0,0 +1,14 @@
package com.jsl.oa.controllers;
import com.jsl.oa.utils.BaseResponse;
import com.jsl.oa.utils.ResultUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
@RequestMapping("/")
public BaseResponse index() {
return ResultUtil.success("欢迎使用JSL-OA系统服务器处于正常状态");
}
}

View File

@ -2,37 +2,40 @@ package com.jsl.oa.exception;
import com.jsl.oa.utils.BaseResponse;
import com.jsl.oa.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.regex.Pattern;
@ControllerAdvice
@Slf4j
@RestControllerAdvice
public class ProcessException {
@ExceptionHandler(value = Exception.class)
public ResponseEntity<BaseResponse> businessException(@NotNull Exception e) {
e.printStackTrace();
return ResultUtil.error("Exception", 500, "服务器异常");
}
@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
public ResponseEntity<BaseResponse> businessMethodNotAllowedException() {
log.debug("请求方法错误");
return ResultUtil.error("MethodNotAllowed", 405, "请求方法错误");
}
@ExceptionHandler(value = SQLIntegrityConstraintViolationException.class)
public ResponseEntity<BaseResponse> businessSQLIntegrityConstraintViolationException(@NotNull SQLIntegrityConstraintViolationException e) {
if (Pattern.matches(".*Duplicate entry.*", e.getMessage())) {
return ResultUtil.error("DuplicateEntry", 400, "数据重复");
} else if (Pattern.matches(".*Cannot delete or update a parent row: a foreign key constraint fails.*", e.getMessage())) {
return ResultUtil.error("DataAssociation", 400, "数据存在关联,无法删除");
} else {
return ResultUtil.error("DatabaseError", 400, "数据库异常");
@ExceptionHandler(value = DuplicateKeyException.class)
public ResponseEntity<BaseResponse> businessDuplicateKeyException(@NotNull DuplicateKeyException e) {
log.debug(e.getMessage(), e);
return ResultUtil.error("DuplicateEntry", 400, "数据重复/外键约束");
}
@ExceptionHandler(value = HttpMessageNotReadableException.class)
public ResponseEntity<BaseResponse> businessHttpMessageNotReadableException(HttpMessageNotReadableException e) {
log.debug(e.getMessage(), e);
return ResultUtil.error("HttpMessageNotReadable", 400, "请求参数错误");
}
@ExceptionHandler(value = Exception.class)
public ResponseEntity<BaseResponse> businessException(@NotNull Exception e) {
log.error(e.getMessage(), e);
return ResultUtil.error("Exception", 500, "服务器异常");
}
}

View File

@ -1,10 +1,10 @@
package com.jsl.oa.mapper;
import com.jsl.oa.model.voData.RoleAddUserVO;
import com.jsl.oa.model.voData.RoleRemoveUserVO;
import com.jsl.oa.model.doData.RoleUserDO;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface RoleMapper {
@ -14,4 +14,7 @@ public interface RoleMapper {
@Delete("delete from organize_oa.oa_role_user where uid=#{uid}")
void roleRemoveUser(Long uid);
@Select("SELECT * FROM organize_oa.oa_role_user WHERE uid=#{uid}")
RoleUserDO getRoleByUid(Long uid);
}

View File

@ -40,4 +40,7 @@ public interface UserMapper {
UserDO getUserByJobId(String user);
void userEditProfile(UserEditProfileVO userEditProfileVO);
@Update("UPDATE organize_oa.oa_user SET password = #{newPassword} WHERE id = #{id}")
boolean updateUserPassword(Long id, String newPassword);
}

View File

@ -0,0 +1,15 @@
package com.jsl.oa.model.voData;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class UserChangePasswordVO {
@NotBlank(message = "旧密码不能为空")
private String oldPassword;
@NotBlank(message = "新密码不能为空")
private String newPassword;
@NotBlank(message = "确认密码不能为空")
private String confirmPassword;
}

View File

@ -1,6 +1,6 @@
package com.jsl.oa.model.voData;
import lombok.Getter;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
@ -14,11 +14,11 @@ import javax.validation.constraints.Pattern;
* @version v1.0.0
* @since v1.0.0
*/
@Getter
@Data
public class UserLoginVO {
@Pattern(regexp = "^[0-9A-Za-z_]+$", message = "支持用户名/手机号/工号登陆")
@NotBlank(message = "用户名不能为空")
private String username;
private String user;
@NotBlank(message = "密码不能为空")
private String password;
}

View File

@ -1,5 +1,6 @@
package com.jsl.oa.model.voData;
import com.jsl.oa.model.doData.RoleUserDO;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
@ -25,4 +26,5 @@ public class UserReturnBackVO {
private Short age;
private Short sex;
private String token;
private RoleUserDO role;
}

View File

@ -1,9 +1,12 @@
package com.jsl.oa.services;
import com.jsl.oa.model.voData.UserChangePasswordVO;
import com.jsl.oa.model.voData.UserLoginVO;
import com.jsl.oa.model.voData.UserRegisterVO;
import com.jsl.oa.utils.BaseResponse;
import javax.servlet.http.HttpServletRequest;
/**
* <h1>用户认证服务接口</h1>
* <hr/>
@ -55,4 +58,23 @@ public interface AuthService {
* @return {@link BaseResponse}
*/
BaseResponse authLoginSendEmailCode(String email);
/**
* <h2>用户修改密码</h2>
* <hr/>
* 用户修改密码服务类操作
*
* @param userChangePasswordVO 用户修改密码信息
* @return {@link BaseResponse}
*/
BaseResponse authChangePassword(HttpServletRequest request, UserChangePasswordVO userChangePasswordVO);
/**
* <h2>用户登出</h2>
* <hr/>
* 用户登出服务类操作
*
* @return {@link BaseResponse}
*/
BaseResponse authLogout(HttpServletRequest request);
}

View File

@ -2,8 +2,11 @@ package com.jsl.oa.services.impl;
import com.jsl.oa.common.constant.BusinessConstants;
import com.jsl.oa.exception.BusinessException;
import com.jsl.oa.mapper.RoleMapper;
import com.jsl.oa.mapper.UserMapper;
import com.jsl.oa.model.doData.RoleUserDO;
import com.jsl.oa.model.doData.UserDO;
import com.jsl.oa.model.voData.UserChangePasswordVO;
import com.jsl.oa.model.voData.UserLoginVO;
import com.jsl.oa.model.voData.UserRegisterVO;
import com.jsl.oa.model.voData.UserReturnBackVO;
@ -11,11 +14,14 @@ import com.jsl.oa.services.AuthService;
import com.jsl.oa.services.MailService;
import com.jsl.oa.utils.*;
import com.jsl.oa.utils.redis.EmailRedisUtil;
import com.jsl.oa.utils.redis.TokenRedisUtil;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.regex.Pattern;
/**
@ -31,8 +37,11 @@ import java.util.regex.Pattern;
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {
private final UserMapper userMapper;
private final RoleMapper roleMapper;
private final MailService mailService;
private final EmailRedisUtil<Integer> emailRedisUtil;
private final TokenRedisUtil<String> tokenRedisUtil;
@Override
public BaseResponse authRegister(@NotNull UserRegisterVO userRegisterVO) {
@ -71,34 +80,23 @@ public class AuthServiceImpl implements AuthService {
public BaseResponse authLogin(@NotNull UserLoginVO userLoginVO) {
// 检查用户是否存在
UserDO userDO;
if (Pattern.matches("^[0-9A-Za-z_]{3,40}$", userLoginVO.getUsername())) {
if (Pattern.matches("^[0-9A-Za-z_]{3,40}$", userLoginVO.getUser())) {
// 是否为用户名
userDO = userMapper.getUserInfoByUsername(userLoginVO.getUsername());
} else if (Pattern.matches("^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$", userLoginVO.getUsername())) {
userDO = userMapper.getUserInfoByUsername(userLoginVO.getUser());
} else if (Pattern.matches("^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$", userLoginVO.getUser())) {
// 是否为手机号
userDO = userMapper.getUserInfoByPhone(userLoginVO.getUsername());
} else if (Pattern.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", userLoginVO.getUsername())) {
userDO = userMapper.getUserInfoByPhone(userLoginVO.getUser());
} else if (Pattern.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", userLoginVO.getUser())) {
// 是否为邮箱
return ResultUtil.error(ErrorCode.EMAIL_LOGIN_NOT_SUPPORT);
} else {
// 工号
userDO = userMapper.getUserByJobId(userLoginVO.getUsername());
userDO = userMapper.getUserByJobId(userLoginVO.getUser());
}
if (userDO != null) {
// 获取用户并登陆
if (BCrypt.checkpw(userLoginVO.getPassword(), userDO.getPassword())) {
UserReturnBackVO userReturnBackVO = new UserReturnBackVO();
// 授权 Token
String token = JwtUtil.generateToken(userDO.getId());
userReturnBackVO.setAddress(userDO.getAddress())
.setAge(userDO.getAge())
.setEmail(userDO.getEmail())
.setJobId(userDO.getJobId())
.setPhone(userDO.getPhone())
.setSex(userDO.getSex())
.setUsername(userDO.getUsername())
.setToken(token);
return ResultUtil.success("登陆成功", userReturnBackVO);
return this.encapsulateDisplayContent(userDO);
} else {
return ResultUtil.error(ErrorCode.WRONG_PASSWORD);
}
@ -117,18 +115,7 @@ public class AuthServiceImpl implements AuthService {
if (emailRedisUtil.delData(BusinessConstants.BUSINESS_LOGIN, email)) {
// 邮箱获取用户
UserDO userDO = userMapper.getUserInfoByEmail(email);
// 授权 Token
String token = JwtUtil.generateToken(userDO.getId());
UserReturnBackVO userReturnBackVO = new UserReturnBackVO();
userReturnBackVO.setAddress(userDO.getAddress())
.setAge(userDO.getAge())
.setEmail(userDO.getEmail())
.setJobId(userDO.getJobId())
.setPhone(userDO.getPhone())
.setSex(userDO.getSex())
.setUsername(userDO.getUsername())
.setToken(token);
return ResultUtil.success("登陆成功", userReturnBackVO);
return this.encapsulateDisplayContent(userDO);
} else {
return ResultUtil.error(ErrorCode.DATABASE_DELETE_ERROR);
}
@ -159,4 +146,76 @@ public class AuthServiceImpl implements AuthService {
return ResultUtil.error(ErrorCode.USER_NOT_EXIST);
}
}
@Override
public BaseResponse authChangePassword(HttpServletRequest request, @NotNull UserChangePasswordVO userChangePasswordVO) {
// 检查新密码输入无误
if (!userChangePasswordVO.getNewPassword().equals(userChangePasswordVO.getConfirmPassword())) {
return ResultUtil.error(ErrorCode.PASSWORD_NOT_SAME);
}
// 检查用户
UserDO userDO = userMapper.getUserById(Processing.getAuthHeader(request));
if (userDO != null) {
// 检查旧密码
if (BCrypt.checkpw(userChangePasswordVO.getOldPassword(), userDO.getPassword())) {
// 更新密码
if (userMapper.updateUserPassword(userDO.getId(), BCrypt.hashpw(userChangePasswordVO.getNewPassword(), BCrypt.gensalt()))) {
return ResultUtil.success("修改成功");
} else {
return ResultUtil.error(ErrorCode.DATABASE_UPDATE_ERROR);
}
} else {
return ResultUtil.error(ErrorCode.WRONG_PASSWORD);
}
} else {
return ResultUtil.error(ErrorCode.USER_NOT_EXIST);
}
}
@Override
public BaseResponse authLogout(HttpServletRequest request) {
// 获取用户
UserDO userDO = userMapper.getUserById(Processing.getAuthHeader(request));
// 删除Token
if (tokenRedisUtil.delData(BusinessConstants.BUSINESS_LOGIN, userDO.getId().toString())) {
return ResultUtil.success("登出成功");
} else {
return ResultUtil.error(ErrorCode.DATABASE_DELETE_ERROR);
}
}
/**
* <h2>封装返回内容</h2>
* <hr/>
* 封装返回内容
*
* @param userDO 用户信息
* @return {@link BaseResponse}
*/
private @NotNull BaseResponse encapsulateDisplayContent(@NotNull UserDO userDO) {
// 授权 Token
String token = JwtUtil.generateToken(userDO.getId());
UserReturnBackVO userReturnBackVO = new UserReturnBackVO();
// Token 上传到 Redis
tokenRedisUtil.setData(BusinessConstants.BUSINESS_LOGIN, userDO.getId().toString(), token, 1440);
// 获取用户角色
RoleUserDO getUserRole = roleMapper.getRoleByUid(userDO.getId());
if (getUserRole == null) {
getUserRole = new RoleUserDO();
getUserRole.setRid(0L)
.setCreatedAt(new Timestamp(System.currentTimeMillis()));
} else {
getUserRole.setUid(null);
}
userReturnBackVO.setAddress(userDO.getAddress())
.setAge(userDO.getAge())
.setEmail(userDO.getEmail())
.setJobId(userDO.getJobId())
.setPhone(userDO.getPhone())
.setSex(userDO.getSex())
.setUsername(userDO.getUsername())
.setToken(token)
.setRole(getUserRole);
return ResultUtil.success("登陆成功", userReturnBackVO);
}
}

View File

@ -13,7 +13,9 @@ public enum ErrorCode {
UNAUTHORIZED("Unauthorized", 40100, "未授权"),
TOKEN_EXPIRED("TokenExpired", 40101, "Token已过期"),
VERIFICATION_INVALID("VerificationInvalid", 40102, "验证码无效"),
TOKEN_NOT_EXIST("TokenNotExist", 40103, "Token不存在"),
EMAIL_LOGIN_NOT_SUPPORT("EmailLoginNotSupport", 40300, "请使用邮箱登陆"),
PASSWORD_NOT_SAME("PasswordNotSame", 40301, "两次密码不一致"),
DATABASE_INSERT_ERROR("DatabaseInsertError", 50010, "数据库插入错误"),
DATABASE_UPDATE_ERROR("DatabaseUpdateError", 50011, "数据库更新错误"),
DATABASE_DELETE_ERROR("DatabaseDeleteError", 50012, "数据库删除错误"),

View File

@ -6,6 +6,7 @@ import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import java.security.Key;
@ -21,6 +22,7 @@ import java.util.regex.Pattern;
* @see com.jsl.oa.config.JwtFilter
* @since v1.1.0
*/
@Slf4j
public class JwtUtil {
private static final long EXPIRATION_TIME = 86400000;
@ -52,9 +54,10 @@ public class JwtUtil {
try {
Long getTokenInUserId = getUserId(token);
// 验证用户名是否匹配
log.debug("Token值" + getTokenInUserId.toString());
return Pattern.matches("^[0-9]+$", getTokenInUserId.toString());
} catch (Exception e) {
e.printStackTrace();
log.debug("Token验证失败", e);
return false;
}
}
@ -77,8 +80,9 @@ public class JwtUtil {
long userId;
try {
userId = Long.parseLong(claimsJws.getBody().getSubject());
log.debug("用户ID" + userId);
} catch (NumberFormatException exception) {
exception.printStackTrace();
log.debug("用户ID格式错误", exception);
throw new NumberFormatException("用户ID格式错误");
}
return userId;

View File

@ -1,9 +1,11 @@
package com.jsl.oa.utils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Random;
@ -126,6 +128,24 @@ public class Processing {
return result.toString();
}
/**
* <h2>获取Authorization Header</h2>
* <hr/>
* 用于获取Authorization Header
*
* @param request 请求
*/
public static @Nullable Long getAuthHeader(@NotNull HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (token == null || token.isEmpty()) {
return null;
} else {
// 解析Bearer后面的令牌
token = token.replace("Bearer ", "");
return JwtUtil.getUserId(token);
}
}
private static char getCharFromIndex(int index) {
// 生成字符集合可以根据需要自定义
String charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

View File

@ -1,38 +1,57 @@
package com.jsl.oa.utils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.springframework.http.ResponseEntity;
@Slf4j
public class ResultUtil {
public static BaseResponse success() {
@Contract(" -> new")
public static @NotNull BaseResponse success() {
log.debug("请求接口成功");
return new BaseResponse("Success", 200, "操作成功", null);
}
public static BaseResponse success(String message) {
@Contract("_ -> new")
public static @NotNull BaseResponse success(String message) {
log.debug("请求接口成功");
return new BaseResponse("Success", 200, message, null);
}
public static BaseResponse success(Object data) {
@Contract(value = "_ -> new", pure = true)
public static @NotNull BaseResponse success(Object data) {
log.debug("请求接口成功");
return new BaseResponse("Success", 200, "操作成功", data);
}
public static BaseResponse success(String message, Object data) {
@Contract(value = "_, _ -> new", pure = true)
public static @NotNull BaseResponse success(String message, Object data) {
log.debug("请求接口成功");
return new BaseResponse("Success", 200, message, data);
}
public static BaseResponse error(ErrorCode errorCode) {
@Contract("_ -> new")
public static @NotNull BaseResponse error(@NotNull ErrorCode errorCode) {
log.debug("请求接口错误[" + errorCode.getCode() + "] " + errorCode.getMessage());
return new BaseResponse(errorCode.getOutput(), errorCode.getCode(), errorCode.getMessage());
}
public static BaseResponse error(ErrorCode errorCode, Object data) {
@Contract("_, _ -> new")
public static @NotNull BaseResponse error(@NotNull ErrorCode errorCode, Object data) {
log.debug("请求接口错误[" + errorCode.getCode() + "] " + errorCode.getMessage());
return new BaseResponse(errorCode.getOutput(), errorCode.getCode(), errorCode.getMessage(), data);
}
public static BaseResponse error(String output, Integer code, String message, Object data) {
@Contract(value = "_, _, _, _ -> new", pure = true)
public static @NotNull BaseResponse error(String output, Integer code, String message, Object data) {
log.debug("请求接口错误[" + code + "] " + message);
return new BaseResponse(output, code, message, data);
}
public static ResponseEntity<BaseResponse> error(String output, Integer code, String message) {
public static @NotNull ResponseEntity<BaseResponse> error(String output, Integer code, String message) {
log.debug("请求接口错误[" + code + "] " + message);
return ResponseEntity.status(code)
.body(new BaseResponse(output, code, message));
}

View File

@ -0,0 +1,51 @@
package com.jsl.oa.utils.redis;
import com.jsl.oa.common.constant.BusinessConstants;
import com.jsl.oa.common.constant.RedisConstant;
import com.jsl.oa.config.redis.RedisOperating;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
public class TokenRedisUtil<R> extends RedisOperating<R> {
public TokenRedisUtil(RedisTemplate<String, R> redisTemplate, StringRedisTemplate stringRedisTemplate) {
super(redisTemplate, stringRedisTemplate);
}
@Override
public Long getExpiredAt(@NotNull BusinessConstants businessConstants, String field) {
String key = RedisConstant.TYPE_AUTH + RedisConstant.TABLE_TOKEN + businessConstants.getValue() + field;
return redisTemplate.getExpire(key);
}
@Override
public Boolean delData(@NotNull BusinessConstants businessConstants, String field) {
String key = RedisConstant.TYPE_AUTH + RedisConstant.TABLE_TOKEN + businessConstants.getValue() + field;
return redisTemplate.delete(key);
}
@Override
public R getData(@NotNull BusinessConstants businessConstants, String field) {
String key = RedisConstant.TYPE_AUTH + RedisConstant.TABLE_TOKEN + businessConstants.getValue() + field;
return redisTemplate.opsForValue().get(key);
}
@Override
public Boolean setData(@NotNull BusinessConstants businessConstants, String field, R value, Integer time) {
// 处理数据
String key = RedisConstant.TYPE_AUTH + RedisConstant.TABLE_TOKEN + businessConstants.getValue() + field;
redisTemplate.opsForValue().set(key, value);
redisTemplate.expire(key, time, TimeUnit.MINUTES);
return true;
}
public List<R> getList(@NotNull BusinessConstants businessConstants) {
String key = RedisConstant.TYPE_AUTH + RedisConstant.TABLE_TOKEN + businessConstants.getValue() + "*";
return this.getList(key);
}
}