feat:
- 完善注册功能 - 完善全局异常处理器
This commit is contained in:
parent
8937ec945a
commit
7fa1a38e33
@ -56,8 +56,8 @@ public class SecurityConfig {
|
||||
)
|
||||
// 认证请求
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/login").permitAll()
|
||||
// .requestMatchers("/users", "/users/**").hasRole("ADMIN")
|
||||
.requestMatchers("/auth/**").permitAll()
|
||||
.requestMatchers("/auth/register").permitAll()
|
||||
.anyRequest().access((authenticationSupplier, requestAuthorizationContext) -> {
|
||||
HttpServletRequest request = requestAuthorizationContext.getRequest();
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
package asia.yulinling.workflow.controller;
|
||||
|
||||
import asia.yulinling.workflow.dto.request.LoginRequest;
|
||||
import asia.yulinling.workflow.dto.request.RegisterRequest;
|
||||
import asia.yulinling.workflow.dto.response.JWTAuthResponse;
|
||||
import asia.yulinling.workflow.model.ApiResponse;
|
||||
import asia.yulinling.workflow.service.AuthService;
|
||||
import asia.yulinling.workflow.utils.ResponseUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -22,16 +25,27 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/auth")
|
||||
@Slf4j
|
||||
public class AuthController {
|
||||
|
||||
private final AuthService authenticate;
|
||||
private final AuthService authService;
|
||||
|
||||
@PostMapping("/login")
|
||||
public ApiResponse<JWTAuthResponse> login(@RequestBody LoginRequest loginRequest) {
|
||||
String token = authenticate.login(loginRequest);
|
||||
String token = authService.login(loginRequest);
|
||||
JWTAuthResponse jwtAuthResponse = new JWTAuthResponse(token);
|
||||
return ApiResponse.ofSuccess(jwtAuthResponse);
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
public ApiResponse<?> logout(HttpServletRequest request) throws SecurityException {
|
||||
return authService.logout(request);
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
public ApiResponse<?> register(@RequestBody RegisterRequest registerRequest) throws Exception {
|
||||
return authService.register(registerRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
package asia.yulinling.workflow.dto.request;
|
||||
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 注册请求类
|
||||
* </p>
|
||||
*
|
||||
* @author YLL
|
||||
* @since 2025/6/19
|
||||
*/
|
||||
@Data
|
||||
public class RegisterRequest {
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@NotBlank(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 二次密码
|
||||
*/
|
||||
@NotBlank(message = "确认密码不能为空")
|
||||
private String confirmPassword;
|
||||
|
||||
/**
|
||||
* 电子邮箱
|
||||
*/
|
||||
@Email
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
private String birthday;
|
||||
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
private Integer sex;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@Max(11)
|
||||
@Min(5)
|
||||
private String phone;
|
||||
}
|
||||
@ -1,9 +1,12 @@
|
||||
package asia.yulinling.workflow.exception.handler;
|
||||
|
||||
import asia.yulinling.workflow.exception.BaseException;
|
||||
import asia.yulinling.workflow.exception.JsonException;
|
||||
import asia.yulinling.workflow.exception.PageException;
|
||||
import asia.yulinling.workflow.model.ApiResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@ -30,9 +33,9 @@ public class GlobalExceptionHandler {
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public ApiResponse<?> jsonErrorHandler(JsonException e) {
|
||||
log.error(e.getMessage());
|
||||
return ApiResponse.ofException(e);
|
||||
public ApiResponse<?> cathAllErrorHandler(Exception e) {
|
||||
log.error("json error:{}", e.getMessage());
|
||||
return ApiResponse.of(500, e.getMessage(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -56,7 +56,7 @@ public class ApiResponse<T> {
|
||||
* @param data 返回数据
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public static <T> ApiResponse<T> of(Integer code, String message, T data) {
|
||||
public static <T> ApiResponse<T> of(Integer code, String message, Object data) {
|
||||
return new ApiResponse<>(code, message, data);
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ public class ApiResponse<T> {
|
||||
* @param <T> {@link BaseException} 子类
|
||||
* @return ApiResponse
|
||||
*/
|
||||
public static <T extends BaseException> ApiResponse<T> ofException(T t, T data) {
|
||||
public static <T extends BaseException> ApiResponse<T> ofException(T t, Object data) {
|
||||
return of(t.getCode(), t.getMessage(), data);
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import asia.yulinling.workflow.model.ApiResponse;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -20,6 +21,7 @@ import java.io.IOException;
|
||||
* @since 2025/6/13
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@ -31,6 +33,8 @@ public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) throws IOException {
|
||||
|
||||
log.error("AuthenticationException: {}",authException.getMessage());
|
||||
|
||||
// 1. 设置res 401
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package asia.yulinling.workflow.service;
|
||||
|
||||
import asia.yulinling.workflow.dto.request.LoginRequest;
|
||||
import asia.yulinling.workflow.dto.request.RegisterRequest;
|
||||
import asia.yulinling.workflow.model.ApiResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -12,4 +15,8 @@ import asia.yulinling.workflow.dto.request.LoginRequest;
|
||||
*/
|
||||
public interface AuthService {
|
||||
String login(LoginRequest loginRequest);
|
||||
|
||||
ApiResponse<?> logout(HttpServletRequest request) throws SecurityException;
|
||||
|
||||
ApiResponse<?> register(RegisterRequest request) throws Exception;
|
||||
}
|
||||
|
||||
@ -1,15 +1,29 @@
|
||||
package asia.yulinling.workflow.service.impl;
|
||||
|
||||
import asia.yulinling.workflow.constant.Status;
|
||||
import asia.yulinling.workflow.dto.request.LoginRequest;
|
||||
import asia.yulinling.workflow.dto.request.RegisterRequest;
|
||||
import asia.yulinling.workflow.mapper.UserMapper;
|
||||
import asia.yulinling.workflow.model.ApiResponse;
|
||||
import asia.yulinling.workflow.model.entity.User;
|
||||
import asia.yulinling.workflow.service.AuthService;
|
||||
import asia.yulinling.workflow.utils.JwtUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -26,6 +40,8 @@ public class AuthServiceImpl implements AuthService {
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final JwtUtil jwtUtil;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public String login(LoginRequest loginRequest) {
|
||||
@ -33,8 +49,55 @@ public class AuthServiceImpl implements AuthService {
|
||||
loginRequest.getUsername(), loginRequest.getPassword()
|
||||
));
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
String token =jwtUtil.generateToken(authentication, false);
|
||||
String token = jwtUtil.generateToken(authentication, false);
|
||||
log.info("generateToken: {}", token);
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse<?> logout(HttpServletRequest request) throws SecurityException {
|
||||
try {
|
||||
jwtUtil.invalidateToken(request);
|
||||
} catch (SecurityException e) {
|
||||
log.info("invalidateToken: {}", e.getMessage());
|
||||
}
|
||||
return ApiResponse.ofStatus(Status.LOGOUT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse<?> register(RegisterRequest request) throws Exception {
|
||||
|
||||
if (!StrUtil.equals(request.getConfirmPassword(), request.getPassword())) {
|
||||
log.info("password {}, confirmPassword {}", request.getConfirmPassword(), request.getPassword());
|
||||
return ApiResponse.of(400, "密码不一致", null);
|
||||
}
|
||||
|
||||
if (userMapper.exists(new LambdaQueryWrapper<User>().eq(User::getUsername, request.getUsername()))) {
|
||||
return ApiResponse.of(400, "用户名已存在", null);
|
||||
}
|
||||
|
||||
if (userMapper.exists(new LambdaQueryWrapper<User>().eq(User::getEmail, request.getEmail()))) {
|
||||
return ApiResponse.of(400, "邮箱已注册", null);
|
||||
}
|
||||
|
||||
User user = new User();
|
||||
user.setUsername(request.getUsername());
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
user.setEmail(request.getEmail());
|
||||
user.setNickname(request.getNickname());
|
||||
user.setPhone(request.getPhone());
|
||||
user.setBirthday(request.getBirthday());
|
||||
user.setStatus(1);
|
||||
user.setUpdateTime(new Date());
|
||||
|
||||
log.info("User: {}", user);
|
||||
try {
|
||||
userMapper.insert(user);
|
||||
} catch (Exception e) {
|
||||
log.error("insertUser Error: {}", e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return ApiResponse.of(200, "注册成功", null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
DROP TABLE IF EXISTS `wk_user`;
|
||||
CREATE TABLE `wk_user`
|
||||
(
|
||||
`id` bigint(64) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
|
||||
`username` VARCHAR(32) NOT NULL UNIQUE COMMENT '用户名',
|
||||
`nickname` VARCHAR(32) NOT NULL UNIQUE COMMENT '昵称',
|
||||
`id` bigint(64) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
|
||||
`username` VARCHAR(32) NOT NULL UNIQUE COMMENT '用户名',
|
||||
`nickname` VARCHAR(32) DEFAULT '默认用户' COMMENT '昵称',
|
||||
`password` VARCHAR(256) NOT NULL COMMENT '加密后的密码',
|
||||
`email` VARCHAR(32) NOT NULL UNIQUE COMMENT '邮箱',
|
||||
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
|
||||
`sex` INT(2) DEFAULT NULL COMMENT '性别,男-1,女-2',
|
||||
`phone` VARCHAR(15) DEFAULT NULL UNIQUE COMMENT '手机号',
|
||||
`status` INT(2) NOT NULL DEFAULT 1 COMMENT '状态 -1:删除 0:警用 1:启用',
|
||||
`create_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '创建时间',
|
||||
`update_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '上次更新时间',
|
||||
`last_login_time` DATETIME DEFAULT NULL COMMENT '上次登录时间'
|
||||
`email` VARCHAR(32) UNIQUE COMMENT '邮箱',
|
||||
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
|
||||
`sex` INT(2) DEFAULT NULL COMMENT '性别,男-1,女-2',
|
||||
`phone` VARCHAR(15) DEFAULT NULL UNIQUE COMMENT '手机号',
|
||||
`status` INT(2) NOT NULL DEFAULT 1 COMMENT '状态 -1:删除 0:警用 1:启用',
|
||||
`create_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '创建时间',
|
||||
`update_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '上次更新时间',
|
||||
`last_login_time` DATETIME DEFAULT NULL COMMENT '上次登录时间'
|
||||
) ENGINE = INNODB
|
||||
DEFAULT CHARSET = UTF8 COMMENT '用户表';
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user