refactor: 拆分出认证服务
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package cn.meowrain.aioj.backend.userservice.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScans;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package cn.meowrain.aioj.backend.userservice.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Data
|
||||
@ConfigurationProperties(value = JwtPropertiesConfiguration.PREFIX)
|
||||
public class JwtPropertiesConfiguration {
|
||||
public static final String PREFIX = "jwt";
|
||||
/**
|
||||
* JWT 密钥(必须 32 字节以上)
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 过期时间(单位:毫秒)
|
||||
*/
|
||||
private Long expire;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package cn.meowrain.aioj.backend.userservice.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
|
||||
import cn.meowrain.aioj.backend.userservice.security.JwtAuthenticationFilter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfiguration {
|
||||
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
|
||||
public SecurityConfiguration(JwtAuthenticationFilter jwtAuthenticationFilter) {
|
||||
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.csrf(csrf -> csrf.disable())
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(
|
||||
"/auth/**",
|
||||
"/doc.html",
|
||||
"/swagger-ui/**",
|
||||
"/swagger-resources/**",
|
||||
"/webjars/**",
|
||||
"/v3/api-docs/**",
|
||||
"/favicon.ico"
|
||||
)
|
||||
.permitAll()
|
||||
.anyRequest().authenticated())
|
||||
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
|
||||
return configuration.getAuthenticationManager();
|
||||
}
|
||||
}
|
||||
@@ -2,35 +2,31 @@ package cn.meowrain.aioj.backend.userservice.controller;
|
||||
|
||||
import cn.meowrain.aioj.backend.framework.web.Result;
|
||||
import cn.meowrain.aioj.backend.framework.web.Results;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserLoginRequest;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequest;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.resp.UserLoginResponse;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.resp.UserAuthRespDTO;
|
||||
import cn.meowrain.aioj.backend.userservice.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.springframework.web.bind.annotation.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@RestController()
|
||||
@RequestMapping("/auth")
|
||||
@RequestMapping("/v1/user")
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
|
||||
@PostMapping("/register")
|
||||
public Result<Long> register(@RequestBody UserRegisterRequest userRegisterRequest) {
|
||||
public Result<Long> register(@RequestBody UserRegisterRequestDTO userRegisterRequest) {
|
||||
Long l = userService.userRegister(userRegisterRequest);
|
||||
return Results.success(l);
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public Result<UserLoginResponse> login(@RequestBody UserLoginRequest userLoginRequest) {
|
||||
UserLoginResponse userLoginResponse = userService.userLogin(userLoginRequest);
|
||||
return Results.success(userLoginResponse);
|
||||
|
||||
@GetMapping("/inner/get-by-username")
|
||||
public Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount) {
|
||||
UserAuthRespDTO userAuthDTO = userService.findAuthInfoByUserAccount(userAccount);
|
||||
return Results.success(userAuthDTO);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package cn.meowrain.aioj.backend.userservice.dto.chains;
|
||||
|
||||
import cn.meowrain.aioj.backend.framework.designpattern.chains.AbstractChianHandler;
|
||||
import cn.meowrain.aioj.backend.framework.errorcode.ErrorCode;
|
||||
import cn.meowrain.aioj.backend.framework.exception.ClientException;
|
||||
import cn.meowrain.aioj.backend.userservice.common.enums.ChainMarkEnums;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserLoginRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserLoginRequestParamVerifyChain implements AbstractChianHandler<UserLoginRequest> {
|
||||
@Override
|
||||
public void handle(UserLoginRequest requestParam) {
|
||||
if (StringUtils.isAnyBlank(requestParam.getUserAccount(), requestParam.getUserPassword())) {
|
||||
throw new ClientException("参数为空", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserAccount().length() < 4) {
|
||||
throw new ClientException("账号长度不小于4位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
if (requestParam.getUserPassword().length() < 8) {
|
||||
throw new ClientException("密码长度不小于8位", ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mark() {
|
||||
return ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,16 @@ import cn.meowrain.aioj.backend.framework.designpattern.chains.AbstractChianHand
|
||||
import cn.meowrain.aioj.backend.framework.errorcode.ErrorCode;
|
||||
import cn.meowrain.aioj.backend.framework.exception.ClientException;
|
||||
import cn.meowrain.aioj.backend.userservice.common.enums.ChainMarkEnums;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequest;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserRegisterRequestParamVerifyChain implements AbstractChianHandler<UserRegisterRequest> {
|
||||
public class UserRegisterRequestParamVerifyChain implements AbstractChianHandler<UserRegisterRequestDTO> {
|
||||
@Override
|
||||
public void handle(UserRegisterRequest requestParam) {
|
||||
public void handle(UserRegisterRequestDTO requestParam) {
|
||||
// 校验参数里面用户名和密码是不是空的
|
||||
if (StringUtils.isAnyBlank(requestParam.getUserAccount(), requestParam.getUserPassword())) {
|
||||
throw new ClientException("参数为空", ErrorCode.PARAMS_ERROR);
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package cn.meowrain.aioj.backend.userservice.dto.chains.context;
|
||||
|
||||
import cn.meowrain.aioj.backend.framework.designpattern.chains.CommonChainContext;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserLoginRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UserLoginRequestParamVerifyContext extends CommonChainContext<UserLoginRequest> {
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package cn.meowrain.aioj.backend.userservice.dto.chains.context;
|
||||
|
||||
import cn.meowrain.aioj.backend.framework.designpattern.chains.CommonChainContext;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequest;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class UserRegisterRequestParamVerifyContext extends CommonChainContext<UserRegisterRequest> {
|
||||
public class UserRegisterRequestParamVerifyContext extends CommonChainContext<UserRegisterRequestDTO> {
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserLoginRequest {
|
||||
public class UserLoginRequestDTO {
|
||||
private String userAccount;
|
||||
private String userPassword;
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
public class UserRegisterRequest {
|
||||
public class UserRegisterRequestDTO {
|
||||
private String userAccount;
|
||||
private String userPassword;
|
||||
private String checkPassword;
|
||||
@@ -0,0 +1,69 @@
|
||||
package cn.meowrain.aioj.backend.userservice.dto.resp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户认证响应体
|
||||
*/
|
||||
@Data
|
||||
public class UserAuthRespDTO {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
/**
|
||||
* 用户密码
|
||||
*/
|
||||
private String userPassword;
|
||||
|
||||
/**
|
||||
* 开放平台id
|
||||
*/
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 公众号openId
|
||||
*/
|
||||
private String mpOpenId;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
|
||||
/**
|
||||
* 用户角色:user/admin/ban
|
||||
*/
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class UserLoginResponse implements Serializable {
|
||||
public class UserLoginResponseDTO implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@@ -8,6 +8,6 @@ import java.io.Serializable;
|
||||
* 用户注册成功响应对象
|
||||
*/
|
||||
@Data
|
||||
public class UserRegisterResponse implements Serializable {
|
||||
public class UserRegisterResponseDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package cn.meowrain.aioj.backend.userservice.security;
|
||||
|
||||
import cn.meowrain.aioj.backend.userservice.dao.entity.User;
|
||||
import cn.meowrain.aioj.backend.userservice.dao.mapper.UserMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
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.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
@Service
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
private final UserMapper userMapper;
|
||||
|
||||
public CustomUserDetailsService(UserMapper userMapper) {
|
||||
this.userMapper = userMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
User user = userMapper.selectOne(Wrappers.lambdaQuery(User.class).eq(User::getUserAccount, username));
|
||||
if (user == null) {
|
||||
throw new UsernameNotFoundException("用户不存在: " + username);
|
||||
}
|
||||
Collection<? extends GrantedAuthority> authorities = Collections
|
||||
.singletonList(new SimpleGrantedAuthority(user.getUserRole()));
|
||||
return new org.springframework.security.core.userdetails.User(user.getUserAccount(), user.getUserPassword(),
|
||||
authorities);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package cn.meowrain.aioj.backend.userservice.security;
|
||||
|
||||
import cn.meowrain.aioj.backend.userservice.dao.entity.User;
|
||||
import cn.meowrain.aioj.backend.userservice.dao.mapper.UserMapper;
|
||||
import cn.meowrain.aioj.backend.userservice.utils.JwtUtil;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* JWT请求过滤器:解析 Authorization 头中的 Bearer token 并设置认证上下文
|
||||
*/
|
||||
@Component
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private final JwtUtil jwtUtil;
|
||||
private final UserMapper userMapper;
|
||||
|
||||
public JwtAuthenticationFilter(JwtUtil jwtUtil, UserMapper userMapper) {
|
||||
this.jwtUtil = jwtUtil;
|
||||
this.userMapper = userMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
String header = request.getHeader("Authorization");
|
||||
if (!StringUtils.hasText(header) || !header.startsWith("Bearer ")) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
String token = header.substring(7);
|
||||
if (!jwtUtil.isTokenValid(token)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Claims claims = jwtUtil.parseClaims(token);
|
||||
String account = claims.getSubject();
|
||||
Long userId = claims.get("userId", Long.class);
|
||||
|
||||
// 避免重复设置
|
||||
if (StringUtils.hasText(account) && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
// 可选:从数据库再查一次,保证用户未被删除/封禁
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user == null || !StringUtils.hasText(user.getUserRole())) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
List<SimpleGrantedAuthority> authorities = Collections
|
||||
.singletonList(new SimpleGrantedAuthority(user.getUserRole()));
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(account,
|
||||
null, authorities);
|
||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 解析失败直接继续,不抛出,保持无状态
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,25 @@
|
||||
package cn.meowrain.aioj.backend.userservice.service;
|
||||
|
||||
import cn.meowrain.aioj.backend.userservice.dao.entity.User;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserLoginRequest;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequest;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.resp.UserLoginResponse;
|
||||
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.resp.UserAuthRespDTO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface UserService extends IService<User> {
|
||||
/**
|
||||
* 用户注册
|
||||
* @param request {@link UserRegisterRequest}
|
||||
* @param request {@link cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO}
|
||||
* @return {@link Long}
|
||||
*/
|
||||
Long userRegister(UserRegisterRequest request);
|
||||
Long userRegister(UserRegisterRequestDTO request);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @param request {@link UserLoginRequest}
|
||||
* @return {@link UserLoginResponse}
|
||||
* 根据用户账号查找用户认证信息
|
||||
* @param userAccount
|
||||
* @return
|
||||
*/
|
||||
UserLoginResponse userLogin(UserLoginRequest request);
|
||||
UserAuthRespDTO findAuthInfoByUserAccount(String userAccount);
|
||||
}
|
||||
|
||||
@@ -1,46 +1,48 @@
|
||||
package cn.meowrain.aioj.backend.userservice.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import cn.meowrain.aioj.backend.framework.errorcode.ErrorCode;
|
||||
import cn.meowrain.aioj.backend.framework.exception.ClientException;
|
||||
import cn.meowrain.aioj.backend.framework.exception.ServiceException;
|
||||
import cn.meowrain.aioj.backend.userservice.common.enums.ChainMarkEnums;
|
||||
import cn.meowrain.aioj.backend.userservice.dao.entity.User;
|
||||
import cn.meowrain.aioj.backend.userservice.dao.mapper.UserMapper;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.chains.context.UserLoginRequestParamVerifyContext;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.chains.context.UserRegisterRequestParamVerifyContext;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserLoginRequest;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequest;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.resp.UserLoginResponse;
|
||||
|
||||
import cn.meowrain.aioj.backend.userservice.dto.req.UserRegisterRequestDTO;
|
||||
import cn.meowrain.aioj.backend.userservice.dto.resp.UserAuthRespDTO;
|
||||
import cn.meowrain.aioj.backend.userservice.service.UserService;
|
||||
import cn.meowrain.aioj.backend.userservice.utils.JwtUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||
private final UserRegisterRequestParamVerifyContext userRegisterRequestParamVerifyContext;
|
||||
private final UserLoginRequestParamVerifyContext userLoginRequestParamVerifyContext;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final JwtUtil jwtUtil;
|
||||
|
||||
@Override
|
||||
public Long userRegister(UserRegisterRequest request) {
|
||||
public Long userRegister(UserRegisterRequestDTO request) {
|
||||
UserAuthRespDTO authInfoByUserAccount = findAuthInfoByUserAccount(request.getUserAccount());
|
||||
if(authInfoByUserAccount!=null){
|
||||
throw new ClientException("重复创建用户");
|
||||
}
|
||||
|
||||
log.info("进行用户注册");
|
||||
userRegisterRequestParamVerifyContext.handler(ChainMarkEnums.USER_REGISTER_REQ_PARAM_VERIFY.getMarkName(),
|
||||
request);
|
||||
// 使用 BCrypt 加密密码
|
||||
Date now = new Date();
|
||||
String encryptPassword = passwordEncoder.encode(request.getUserPassword());
|
||||
String salt = BCrypt.gensalt();
|
||||
String encryptPassword = BCrypt.hashpw(request.getUserPassword(),salt);
|
||||
User user = new User().setUserAccount(request.getUserAccount()).setUserPassword(encryptPassword)
|
||||
.setUserRole("user").setCreateTime(now).setUpdateTime(now);
|
||||
|
||||
|
||||
try {
|
||||
// 需要修改表,使得用户名是唯一的
|
||||
this.save(user);
|
||||
@@ -52,28 +54,15 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
return user.getId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public UserLoginResponse userLogin(UserLoginRequest requestParam) {
|
||||
// 1.校验
|
||||
userLoginRequestParamVerifyContext.handler(ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName(),
|
||||
requestParam);
|
||||
User user = this.baseMapper.selectOne(Wrappers.lambdaQuery(User.class)
|
||||
.eq(User::getUserAccount, requestParam.getUserAccount()));
|
||||
if (ObjectUtil.isNull(user)
|
||||
|| !passwordEncoder.matches(requestParam.getUserPassword(), user.getUserPassword())) {
|
||||
throw new ServiceException("用户不存在或者密码错误", ErrorCode.NOT_LOGIN_ERROR);
|
||||
public UserAuthRespDTO findAuthInfoByUserAccount(String userAccount) {
|
||||
User one = this.lambdaQuery().eq(User::getUserAccount, userAccount).one();
|
||||
UserAuthRespDTO userAuthDTO = new UserAuthRespDTO();
|
||||
if(one!=null){
|
||||
BeanUtils.copyProperties(one, userAuthDTO);
|
||||
return userAuthDTO;
|
||||
}
|
||||
// 生成 JWT
|
||||
String token = jwtUtil.generateToken(user);
|
||||
UserLoginResponse resp = new UserLoginResponse();
|
||||
resp.setId(user.getId());
|
||||
resp.setUserAccount(user.getUserAccount());
|
||||
resp.setUserAvatar(user.getUserAvatar());
|
||||
resp.setUserProfile(user.getUserProfile());
|
||||
resp.setUserRole(user.getUserRole());
|
||||
resp.setCreateTime(user.getCreateTime());
|
||||
resp.setUpdateTime(user.getUpdateTime());
|
||||
resp.setToken(token);
|
||||
return resp;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package cn.meowrain.aioj.backend.userservice.utils;
|
||||
|
||||
import cn.meowrain.aioj.backend.userservice.config.JwtPropertiesConfiguration;
|
||||
import cn.meowrain.aioj.backend.userservice.dao.entity.User;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* JWT工具类
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
public class JwtUtil {
|
||||
private final JwtPropertiesConfiguration jwtConfig;
|
||||
|
||||
private SecretKey getSigningKey() {
|
||||
return Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes());
|
||||
}
|
||||
|
||||
public String generateToken(User user) {
|
||||
long now = System.currentTimeMillis();
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", user.getId());
|
||||
claims.put("role", user.getUserRole());
|
||||
return Jwts.builder()
|
||||
.subject(user.getUserAccount())
|
||||
.issuedAt(new Date(now))
|
||||
.expiration(new Date(now + jwtConfig.getExpire()))
|
||||
.claims(claims)
|
||||
.signWith(getSigningKey(), Jwts.SIG.HS256)
|
||||
.compact();
|
||||
}
|
||||
|
||||
public Claims parseClaims(String token) {
|
||||
return Jwts.parser()
|
||||
.verifyWith(getSigningKey())
|
||||
.build()
|
||||
.parseSignedClaims(token)
|
||||
.getPayload();
|
||||
}
|
||||
|
||||
public boolean isTokenValid(String token) {
|
||||
try {
|
||||
Claims claims = parseClaims(token);
|
||||
Date expiration = claims.getExpiration();
|
||||
return expiration != null && expiration.after(new Date());
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ spring:
|
||||
active: @env@
|
||||
server:
|
||||
port: 10010
|
||||
servlet:
|
||||
context-path: /api
|
||||
springdoc:
|
||||
api-docs:
|
||||
enabled: true
|
||||
@@ -26,7 +28,4 @@ knife4j:
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
jwt:
|
||||
secret: "12345678901234567890123456789012" # 至少32字节!!
|
||||
expire: 86400000 # 24小时(单位:毫秒)
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
Reference in New Issue
Block a user