旗开得胜
This commit is contained in:
parent
be354a98ec
commit
2c4ea1a675
|
@ -1,7 +1,11 @@
|
|||
package com.greenorange.promotion.aop;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.interfaces.Claim;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.greenorange.promotion.annotation.RequiresPermission;
|
||||
import com.greenorange.promotion.common.ErrorCode;
|
||||
|
@ -9,9 +13,11 @@ import com.greenorange.promotion.exception.ThrowUtils;
|
|||
import com.greenorange.promotion.model.entity.UserInfo;
|
||||
import com.greenorange.promotion.model.enums.UserRoleEnum;
|
||||
import com.greenorange.promotion.service.user.UserInfoService;
|
||||
import com.greenorange.promotion.utils.JWTUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.catalina.User;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
|
@ -19,6 +25,7 @@ import org.springframework.stereotype.Component;
|
|||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
|
@ -36,6 +43,9 @@ public class PermissionCheck {
|
|||
private UserInfoService userInfoService;
|
||||
|
||||
|
||||
@Resource
|
||||
private JWTUtils jwtUtils;
|
||||
|
||||
|
||||
/***
|
||||
* 执行拦截
|
||||
|
@ -50,16 +60,21 @@ public class PermissionCheck {
|
|||
UserRoleEnum mustUserRoleEnum = UserRoleEnum.getEnumByValues(mustRole);
|
||||
ThrowUtils.throwIf(mustUserRoleEnum == null, ErrorCode.NO_AUTH_ERROR);
|
||||
// 获取用户权限
|
||||
String token = request.getHeader("token");
|
||||
ThrowUtils.throwIf(StringUtils.isBlank(token), ErrorCode.NOT_LOGIN_ERROR);
|
||||
String id = null;
|
||||
try {
|
||||
id = JWT.decode(token).getAudience().get(0);
|
||||
} catch (JWTDecodeException jwtDecodeException) {
|
||||
log.info("JWT已失效");
|
||||
}
|
||||
UserInfo userInfo = userInfoService.getById(id);
|
||||
ThrowUtils.throwIf(userInfo == null, ErrorCode.OPERATION_ERROR);
|
||||
String token = request.getHeader("Authorization");
|
||||
ThrowUtils.throwIf(StringUtils.isBlank(token), ErrorCode.NO_AUTH_ERROR, "JWT为空");
|
||||
// 解析token
|
||||
DecodedJWT decodedJWT = jwtUtils.verify(token);
|
||||
String userAccount = decodedJWT.getClaim("userAccount").asString();
|
||||
String userPassword = decodedJWT.getClaim("userPassword").asString();
|
||||
// 打印token的过期时间
|
||||
Date expiresAt = decodedJWT.getExpiresAt();
|
||||
String formatExpiresAt = DateUtil.format(expiresAt, "yyyy-MM-dd HH:mm:ss");
|
||||
log.info("Token过期时间为:" + formatExpiresAt);
|
||||
LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.eq(UserInfo::getUserAccount, userAccount).eq(UserInfo::getUserPassword, userPassword);
|
||||
UserInfo userInfo = userInfoService.getOne(lambdaQueryWrapper);
|
||||
ThrowUtils.throwIf(userInfo == null, ErrorCode.OPERATION_ERROR, "用户不存在");
|
||||
|
||||
// 获取用户权限的枚举类
|
||||
String userRole = userInfo.getUserRole();
|
||||
UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValues(userRole);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.greenorange.promotion.config;
|
||||
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springdoc.core.customizers.GlobalOperationCustomizer;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: cxz
|
||||
* @description 为每个接口添加鉴权
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class Knife4jOperationCustomizer implements GlobalOperationCustomizer {
|
||||
@Override
|
||||
public Operation customize(Operation operation, HandlerMethod handlerMethod) {
|
||||
List<SecurityRequirement> security = operation.getSecurity();
|
||||
if (security == null) {
|
||||
security = List.of(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION));
|
||||
operation.setSecurity(security);
|
||||
}
|
||||
return operation;
|
||||
}
|
||||
}
|
|
@ -1,31 +1,39 @@
|
|||
package com.greenorange.promotion.controller.user;
|
||||
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import com.greenorange.promotion.annotation.RequiresPermission;
|
||||
import com.greenorange.promotion.common.BaseResponse;
|
||||
import com.greenorange.promotion.common.ErrorCode;
|
||||
import com.greenorange.promotion.common.ResultUtils;
|
||||
import com.greenorange.promotion.constant.UserConstant;
|
||||
import com.greenorange.promotion.exception.BusinessException;
|
||||
import com.greenorange.promotion.exception.ThrowUtils;
|
||||
import com.greenorange.promotion.model.dto.CommonBatchRequest;
|
||||
import com.greenorange.promotion.model.dto.CommonRequest;
|
||||
import com.greenorange.promotion.model.dto.user.UserInfoAddRequest;
|
||||
import com.greenorange.promotion.model.dto.user.UserInfoLoginRequest;
|
||||
import com.greenorange.promotion.model.dto.user.UserInfoQueryRequest;
|
||||
import com.greenorange.promotion.model.dto.user.UserInfoUpdateRequest;
|
||||
import com.greenorange.promotion.model.entity.UserInfo;
|
||||
import com.greenorange.promotion.model.vo.user.UserInfoVO;
|
||||
import com.greenorange.promotion.service.common.CommonService;
|
||||
import com.greenorange.promotion.service.user.UserInfoService;
|
||||
import com.greenorange.promotion.utils.JWTUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 用户表 控制器
|
||||
|
@ -40,25 +48,55 @@ public class UserInfoController {
|
|||
@Resource
|
||||
private UserInfoService userInfoService;
|
||||
|
||||
|
||||
@Resource
|
||||
private CommonService commonService;
|
||||
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
|
||||
@Resource
|
||||
private JWTUtils jwtUtils;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* web端管理员登录
|
||||
* @param userInfoLoginRequest 用户登录请求体
|
||||
* @return 是否登录成功
|
||||
*/
|
||||
@PostMapping("login")
|
||||
@Operation(summary = "web端管理员登录", description = "参数:用户登录请求体,权限:管理员(boss, admin),方法名:userInfoLogin")
|
||||
public BaseResponse<String> userInfoLogin(@RequestBody UserInfoLoginRequest userInfoLoginRequest, HttpServletRequest request) {
|
||||
String userAccount = userInfoLoginRequest.getUserAccount();
|
||||
String userPassword = userInfoLoginRequest.getUserPassword();
|
||||
ThrowUtils.throwIf(StringUtils.isAnyBlank(userAccount, userPassword), ErrorCode.PARAMS_ERROR);
|
||||
String token = userInfoService.userInfoLogin(userAccount, userPassword, request);
|
||||
return ResultUtils.success(token);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* web端管理员退出登录(用户退出时将 token 加入 Redis 黑名单)
|
||||
* @return 是否退出登录成功
|
||||
*/
|
||||
@PostMapping("logout")
|
||||
@Operation(summary = "web端管理员退出登录", description = "参数:JWT,权限:管理员(boss, admin),方法名:userInfoLogout")
|
||||
@RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
|
||||
public BaseResponse<Boolean> userInfoLogout(@RequestHeader("Authorization") String token) {
|
||||
// 获取 token 的过期时间
|
||||
DecodedJWT decodedJWT = jwtUtils.verify(token);
|
||||
long expirationTime = decodedJWT.getExpiresAt().getTime() - System.currentTimeMillis();
|
||||
|
||||
// 将 token 存入 Redis 黑名单,并设置过期时间与 token 一致
|
||||
redisTemplate.opsForValue().set(token, token, expirationTime, TimeUnit.MILLISECONDS);
|
||||
return ResultUtils.success(true);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * web端管理员登录
|
||||
// * @param userInfoAddRequest 用户表添加请求体
|
||||
// * @return 是否添加成功
|
||||
// */
|
||||
// @PostMapping("add")
|
||||
// @Operation(summary = "web端管理员添加用户表", description = "参数:用户表添加请求体,权限:管理员(boss, admin),方法名:addUserInfo")
|
||||
// @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||
// public BaseResponse<Boolean> addUserInfo(@RequestBody UserInfoAddRequest userInfoAddRequest) {
|
||||
// ThrowUtils.throwIf(userInfoAddRequest == null, ErrorCode.PARAMS_ERROR);
|
||||
// UserInfo userInfo = commonService.copyProperties(userInfoAddRequest, UserInfo.class);
|
||||
// userInfoService.save(userInfo);
|
||||
// return ResultUtils.success(true);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
@ -76,6 +114,7 @@ public class UserInfoController {
|
|||
return ResultUtils.success(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* web端管理员更新用户表
|
||||
* @param userInfoUpdateRequest 用户表更新请求体
|
||||
|
@ -135,6 +174,7 @@ public class UserInfoController {
|
|||
*/
|
||||
@PostMapping("queryById")
|
||||
@Operation(summary = "web端管理员根据id查询用户表", description = "参数:用户表查询请求体,权限:管理员(boss, admin),方法名:queryUserInfoById")
|
||||
@RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
|
||||
public BaseResponse<UserInfoVO> queryUserInfoById(@RequestBody CommonRequest commonRequest) {
|
||||
ThrowUtils.throwIf(commonRequest == null || commonRequest.getId() <= 0, ErrorCode.PARAMS_ERROR);
|
||||
Long id = commonRequest.getId();
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.greenorange.promotion.common.ResultUtils;
|
|||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
@ -23,14 +24,14 @@ public class GlobalExceptionHandler {
|
|||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public BaseResponse<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||
log.error("MethodArgumentNotValidException", e);
|
||||
return ResultUtils.error(ErrorCode.PARAMS_ERROR, "参数验证失败");
|
||||
return ResultUtils.error(ErrorCode.PARAMS_ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
// 处理消息体解析失败的异常
|
||||
@ExceptionHandler(HttpMessageNotReadableException.class)
|
||||
public BaseResponse<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
|
||||
log.error("HttpMessageNotReadableException", e);
|
||||
return ResultUtils.error(ErrorCode.PARAMS_ERROR, "请求参数不正确");
|
||||
return ResultUtils.error(ErrorCode.PARAMS_ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,19 +3,23 @@ package com.greenorange.promotion.model.dto.user;
|
|||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户表添加请求体
|
||||
* 用户添加请求体
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "用户表添加请求体", requiredProperties = {"name", "categoryId", "price", "image", "period", "isShelves"})
|
||||
@Schema(description = "用户表添加请求体", requiredProperties = {"nickName", "userAvatar", "phoneNumber",
|
||||
"userAccount", "userPassword", "invitationCode", "userRole", "parentUserId", "superUserList"})
|
||||
public class UserInfoAddRequest implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
@NotBlank(message = "参数不能为空")
|
||||
@Schema(description = "用户昵称", example = "${field.example}")
|
||||
private String nickName;
|
||||
|
||||
|
@ -28,13 +32,22 @@ public class UserInfoAddRequest implements Serializable {
|
|||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@NotBlank(message = "参数不能为空")
|
||||
@Schema(description = "手机号", example = "${field.example}")
|
||||
private String phoneNumber;
|
||||
|
||||
/**
|
||||
* 密码(建议加密存储)
|
||||
* 账号
|
||||
*/
|
||||
@Schema(description = "密码(建议加密存储)", example = "${field.example}")
|
||||
@NotBlank(message = "参数不能为空")
|
||||
@Schema(description = "账号", example = "${field.example}")
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@NotBlank(message = "参数不能为空")
|
||||
@Schema(description = "密码", example = "${field.example}")
|
||||
private String userPassword;
|
||||
|
||||
/**
|
||||
|
@ -46,6 +59,7 @@ public class UserInfoAddRequest implements Serializable {
|
|||
/**
|
||||
* 用户角色
|
||||
*/
|
||||
@NotBlank(message = "参数不能为空")
|
||||
@Schema(description = "用户角色", example = "${field.example}")
|
||||
private String userRole;
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package com.greenorange.promotion.model.dto.user;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户登录请求体
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "用户登录请求体", requiredProperties = {"userAccount", "userPassword"})
|
||||
public class UserInfoLoginRequest implements Serializable {
|
||||
|
||||
/**
|
||||
* 账号
|
||||
*/
|
||||
@Schema(description = "账号", example = "${field.example}")
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@Schema(description = "密码", example = "${field.example}")
|
||||
private String userPassword;
|
||||
|
||||
}
|
|
@ -7,7 +7,7 @@ import java.io.Serializable;
|
|||
import com.greenorange.promotion.common.PageRequest;
|
||||
|
||||
/**
|
||||
* 用户表查询请求体,继承自分页请求 PageRequest
|
||||
* 用户查询请求体,继承自分页请求 PageRequest
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "用户表查询请求体", requiredProperties = {"current", "pageSize"})
|
||||
|
@ -19,54 +19,12 @@ public class UserInfoQueryRequest extends PageRequest implements Serializable {
|
|||
@Schema(description = "用户表 ID", example = "1")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
@Schema(description = "用户昵称", example = "${field.example}")
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 用户头像URL
|
||||
*/
|
||||
@Schema(description = "用户头像URL", example = "${field.example}")
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@Schema(description = "手机号", example = "${field.example}")
|
||||
private String phoneNumber;
|
||||
|
||||
/**
|
||||
* 密码(建议加密存储)
|
||||
*/
|
||||
@Schema(description = "密码(建议加密存储)", example = "${field.example}")
|
||||
private String userPassword;
|
||||
|
||||
/**
|
||||
* 邀请码
|
||||
*/
|
||||
@Schema(description = "邀请码", example = "${field.example}")
|
||||
private String invitationCode;
|
||||
|
||||
/**
|
||||
* 用户角色
|
||||
*/
|
||||
@Schema(description = "用户角色", example = "${field.example}")
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 上级用户id
|
||||
*/
|
||||
@Schema(description = "上级用户id", example = "${field.example}")
|
||||
private Long parentUserId;
|
||||
|
||||
/**
|
||||
* 上级用户列表(1,2,3)
|
||||
*/
|
||||
@Schema(description = "上级用户列表(1,2,3)", example = "${field.example}")
|
||||
private String superUserList;
|
||||
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
|
@ -7,10 +7,11 @@ import java.io.Serial;
|
|||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户表更新请求体
|
||||
* 用户更新请求体
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "用户表更新请求体", requiredProperties = {"id", "name", "categoryId", "price", "image", "period", "isShelves"})
|
||||
@Schema(description = "用户表更新请求体", requiredProperties = {"id", "nickName", "userAvatar", "phoneNumber",
|
||||
"userAccount", "userPassword", "invitationCode", "userRole", "parentUserId", "superUserList"})
|
||||
public class UserInfoUpdateRequest implements Serializable {
|
||||
|
||||
/**
|
||||
|
@ -38,9 +39,15 @@ public class UserInfoUpdateRequest implements Serializable {
|
|||
private String phoneNumber;
|
||||
|
||||
/**
|
||||
* 密码(建议加密存储)
|
||||
* 账号
|
||||
*/
|
||||
@Schema(description = "密码(建议加密存储)", example = "${field.example}")
|
||||
@Schema(description = "账号", example = "${field.example}")
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@Schema(description = "密码", example = "${field.example}")
|
||||
private String userPassword;
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,7 +37,12 @@ public class UserInfo implements Serializable {
|
|||
private String phoneNumber;
|
||||
|
||||
/**
|
||||
* 密码(建议加密存储)
|
||||
* 账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String userPassword;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||
import com.greenorange.promotion.model.dto.user.UserInfoQueryRequest;
|
||||
import com.greenorange.promotion.model.entity.UserInfo;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author 35880
|
||||
|
@ -17,4 +18,10 @@ public interface UserInfoService extends IService<UserInfo> {
|
|||
* 获取查询条件
|
||||
*/
|
||||
QueryWrapper<UserInfo> getQueryWrapper(UserInfoQueryRequest userInfoQueryRequest);
|
||||
|
||||
|
||||
/**
|
||||
* web端用户登录
|
||||
*/
|
||||
String userInfoLogin(String userAccount, String userPassword, HttpServletRequest request);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,27 @@
|
|||
package com.greenorange.promotion.service.user.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.greenorange.promotion.annotation.RequiresPermission;
|
||||
import com.greenorange.promotion.common.ErrorCode;
|
||||
import com.greenorange.promotion.constant.CommonConstant;
|
||||
import com.greenorange.promotion.exception.ThrowUtils;
|
||||
import com.greenorange.promotion.mapper.UserInfoMapper;
|
||||
import com.greenorange.promotion.model.dto.user.UserInfoQueryRequest;
|
||||
import com.greenorange.promotion.model.entity.UserInfo;
|
||||
import com.greenorange.promotion.service.user.UserInfoService;
|
||||
import com.greenorange.promotion.utils.JWTUtils;
|
||||
import com.greenorange.promotion.utils.SqlUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 35880
|
||||
* @description 针对表【user_info(用户基本信息表)】的数据库操作Service实现
|
||||
|
@ -17,12 +31,41 @@ import org.springframework.stereotype.Service;
|
|||
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
|
||||
implements UserInfoService{
|
||||
|
||||
@Resource
|
||||
private JWTUtils jwtUtils;
|
||||
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
*/
|
||||
@Override
|
||||
public QueryWrapper<UserInfo> getQueryWrapper(UserInfoQueryRequest userInfoQueryRequest) {
|
||||
return null;
|
||||
Long id = userInfoQueryRequest.getId();
|
||||
String phoneNumber = userInfoQueryRequest.getPhoneNumber();
|
||||
String sortField = userInfoQueryRequest.getSortField();
|
||||
String sortOrder = userInfoQueryRequest.getSortOrder();
|
||||
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq(id != null, "id", id);
|
||||
queryWrapper.eq(StringUtils.isNotBlank(phoneNumber), "phoneNumber", phoneNumber);
|
||||
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* web端用户登录
|
||||
*/
|
||||
@Override
|
||||
public String userInfoLogin(String userAccount, String userPassword, HttpServletRequest request) {
|
||||
ThrowUtils.throwIf(userAccount.length() < 6 || userPassword.length() < 6, ErrorCode.PARAMS_ERROR);
|
||||
LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.eq(UserInfo::getUserAccount, userAccount).eq(UserInfo::getUserPassword, userPassword);
|
||||
UserInfo userInfo = this.getOne(lambdaQueryWrapper);
|
||||
ThrowUtils.throwIf(userInfo == null, ErrorCode.OPERATION_ERROR, "用户不存在");
|
||||
Map<String, String> payload = new HashMap<>();
|
||||
payload.put("userAccount", userAccount);
|
||||
payload.put("userPassword", userPassword);
|
||||
return jwtUtils.generateToken(payload);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,18 +4,32 @@ import com.auth0.jwt.JWT;
|
|||
import com.auth0.jwt.JWTCreator;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.greenorange.promotion.common.ErrorCode;
|
||||
import com.greenorange.promotion.exception.ThrowUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Component
|
||||
public class JWTUtils {
|
||||
|
||||
/**
|
||||
* 生成token header.payload.signature
|
||||
*/
|
||||
|
||||
private static final String SECRET = "qingcheng";
|
||||
|
||||
public static String getToken(Map<String, String> map) {
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* 生成JWT token
|
||||
*/
|
||||
public String generateToken(Map<String, String> map) {
|
||||
|
||||
Calendar instance = Calendar.getInstance();
|
||||
// 默认7天过期
|
||||
|
@ -26,14 +40,19 @@ public class JWTUtils {
|
|||
|
||||
// payload
|
||||
map.forEach(builder::withClaim);
|
||||
|
||||
return builder.withExpiresAt(instance.getTime()) //指定令牌过期时间
|
||||
.sign(Algorithm.HMAC256(SECRET));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证token 合法性
|
||||
* 解析JWT token
|
||||
*/
|
||||
public static DecodedJWT verify(String token) {
|
||||
public DecodedJWT verify(String token) {
|
||||
// 检查 token 是否在黑名单中
|
||||
String tokenFromBlacklist = redisTemplate.opsForValue().get(token);
|
||||
ThrowUtils.throwIf(tokenFromBlacklist != null, ErrorCode.NO_AUTH_ERROR, "JWT 已被注销");
|
||||
return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.auth0.jwt.interfaces.JWTVerifier;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class JwtDemo {
|
||||
|
|
Loading…
Reference in New Issue
Block a user