feat(user): 添加更新用户名功能并优化安全配置
- 在 ErrorCode 中新增 USER_UPDATE_USERNAME_FAILED 错误码 - JwtAuthenticationTokenFilter 中增加当前用户名属性设置 - RestAuthenticationEntryPoint 返回状态码改为 403 并更新错误信息 - 新增 UpdateUsernameRequest DTO 用于接收用户名更新请求 - UserController 添加 updateUsername 接口支持修改用户名 - UserInfoService 和其实现类中增加 updateUsername 方法逻辑 - 引入 tokenHead 配置项以支持 JWT 相关操作
This commit is contained in:
@@ -21,7 +21,6 @@ public enum ErrorCode {
|
|||||||
PASSWORD_FORMAT_ERROR(400, "USER-104", "密码需6-20位字符组合"),
|
PASSWORD_FORMAT_ERROR(400, "USER-104", "密码需6-20位字符组合"),
|
||||||
USER_NOT_EXISTS(404, "USER-104", "用户不存在"),
|
USER_NOT_EXISTS(404, "USER-104", "用户不存在"),
|
||||||
USER_ID_INVALID(400, "USER-105", "用户ID无效"),
|
USER_ID_INVALID(400, "USER-105", "用户ID无效"),
|
||||||
|
|
||||||
USER_NOT_EXISTS_OR_PASSWORD_WRONG(401, "USER-105", "用户名不存在或密码错误"),
|
USER_NOT_EXISTS_OR_PASSWORD_WRONG(401, "USER-105", "用户名不存在或密码错误"),
|
||||||
USER_NOT_ENABLED(403, "USER-106", "用户未启用"),
|
USER_NOT_ENABLED(403, "USER-106", "用户未启用"),
|
||||||
USER_NOT_LOGIN(401, "USER-105", "请先登录"),
|
USER_NOT_LOGIN(401, "USER-105", "请先登录"),
|
||||||
@@ -30,6 +29,8 @@ public enum ErrorCode {
|
|||||||
EMAIL_FORMAT_ERROR(400, "USER-108", "邮箱格式无效"),
|
EMAIL_FORMAT_ERROR(400, "USER-108", "邮箱格式无效"),
|
||||||
PHONE_EXISTS(409, "USER-109", "手机号已注册"),
|
PHONE_EXISTS(409, "USER-109", "手机号已注册"),
|
||||||
PHONE_FORMAT_ERROR(400, "USER-110", "手机号格式无效"),
|
PHONE_FORMAT_ERROR(400, "USER-110", "手机号格式无效"),
|
||||||
|
USER_UPDATE_USERNAME_FAILED(400,"USER-111" , "用户名更新失败"),
|
||||||
|
|
||||||
|
|
||||||
// ================== 论坛内容相关 (200-299) ==================
|
// ================== 论坛内容相关 (200-299) ==================
|
||||||
POST_NOT_FOUND(404, "POST-201", "帖子不存在"),
|
POST_NOT_FOUND(404, "POST-201", "帖子不存在"),
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package cn.nopj.chaos_api.dto.request;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UpdateUsernameRequest {
|
||||||
|
@Pattern(regexp = "^[a-zA-Z0-9_-]{5,16}$", message = "用户名需为5-16位字母、数字、_或-")
|
||||||
|
private String username;
|
||||||
|
}
|
||||||
@@ -34,4 +34,12 @@ public interface UserInfoService {
|
|||||||
* @param password 密码
|
* @param password 密码
|
||||||
*/
|
*/
|
||||||
void setUserPassword(@Pattern(regexp = "^[0-9]+$", message = "用户id格式错误") String userId, @Pattern(regexp = "^.{8,16}$", message = "密码长度需为8-16位") String password);
|
void setUserPassword(@Pattern(regexp = "^[0-9]+$", message = "用户id格式错误") String userId, @Pattern(regexp = "^.{8,16}$", message = "密码长度需为8-16位") String password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户名
|
||||||
|
*
|
||||||
|
* @param username 用户名
|
||||||
|
* @param newUsername 新用户名
|
||||||
|
*/
|
||||||
|
void updateUsername(String username, String newUsername);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,5 +71,23 @@ public class UserInfoServiceImpl implements UserInfoService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUsername(String username, String newUsername) {
|
||||||
|
if (newUsername == null || newUsername.isEmpty()){
|
||||||
|
throw new BizException(ErrorCode.USER_UPDATE_USERNAME_FAILED);
|
||||||
|
}
|
||||||
|
User user = userMapper.selectByUsername(username);
|
||||||
|
if (user == null) {
|
||||||
|
throw new BizException(ErrorCode.USER_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
user.setUsername(newUsername);
|
||||||
|
int i = userMapper.updateById(user);
|
||||||
|
log.info("更新用户名结果: {}", i);
|
||||||
|
if (i == 0) {
|
||||||
|
throw new BizException(ErrorCode.USER_UPDATE_USERNAME_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
|||||||
log.info("authorities: {}", authorities);
|
log.info("authorities: {}", authorities);
|
||||||
UsernamePasswordAuthenticationToken authentication =
|
UsernamePasswordAuthenticationToken authentication =
|
||||||
new UsernamePasswordAuthenticationToken(username, null, authorities);
|
new UsernamePasswordAuthenticationToken(username, null, authorities);
|
||||||
|
request.setAttribute("currentUsername", username);
|
||||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
|||||||
response.setContentType("application/json");
|
response.setContentType("application/json");
|
||||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
|
||||||
ApiResult<Object> result = ApiResult.failed("未授权");
|
ApiResult<Object> result = ApiResult.failed(403,"权限不足");
|
||||||
|
|
||||||
String string = JSONObject.toJSONString(result);
|
String string = JSONObject.toJSONString(result);
|
||||||
response.getWriter().print(string);
|
response.getWriter().print(string);
|
||||||
|
|||||||
@@ -2,16 +2,15 @@ package cn.nopj.chaos_api.controller;
|
|||||||
|
|
||||||
|
|
||||||
import cn.nopj.chaos_api.dto.request.SetUserPasswordRequest;
|
import cn.nopj.chaos_api.dto.request.SetUserPasswordRequest;
|
||||||
|
import cn.nopj.chaos_api.dto.request.UpdateUsernameRequest;
|
||||||
import cn.nopj.chaos_api.dto.response.UserinfoResponse;
|
import cn.nopj.chaos_api.dto.response.UserinfoResponse;
|
||||||
import cn.nopj.chaos_api.model.ApiResult;
|
import cn.nopj.chaos_api.model.ApiResult;
|
||||||
import cn.nopj.chaos_api.service.UserInfoService;
|
import cn.nopj.chaos_api.service.UserInfoService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -26,7 +25,8 @@ import java.util.List;
|
|||||||
public class UserController {
|
public class UserController {
|
||||||
@Autowired
|
@Autowired
|
||||||
UserInfoService userInfoService;
|
UserInfoService userInfoService;
|
||||||
|
@Value("${jwt.tokenHead}")
|
||||||
|
private String tokenHead;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有用户信息
|
* 获取所有用户信息
|
||||||
@@ -49,4 +49,15 @@ public class UserController {
|
|||||||
userInfoService.setUserPassword(request.getUserId(), request.getPassword());
|
userInfoService.setUserPassword(request.getUserId(), request.getPassword());
|
||||||
return ApiResult.success("用户密码修改成功");
|
return ApiResult.success("用户密码修改成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户名
|
||||||
|
* @return 更新后用户名
|
||||||
|
* @deprecated 废弃 修改用户名之后token会失效
|
||||||
|
*/
|
||||||
|
@PostMapping("/updateUsername")
|
||||||
|
ApiResult<String> updateUsername(@RequestAttribute("currentUsername") String username,@RequestBody UpdateUsernameRequest request){
|
||||||
|
userInfoService.updateUsername(username, request.getUsername());
|
||||||
|
return ApiResult.success("用户名更新成功");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user