v0.1.5 优化TokenUtil 完善用户操作部分
parent
e7931c8b93
commit
0ca2a5317b
|
|
@ -21,8 +21,8 @@ public class SecurityConfig {
|
|||
.csrf(csrf -> csrf.disable())
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/api/auth/login").permitAll()
|
||||
.requestMatchers("/admin/**").hasAuthority("leader")
|
||||
.requestMatchers("/user/**").hasAuthority("participant")
|
||||
.requestMatchers("/api/admin/**").hasAuthority("leader")
|
||||
.requestMatchers("/api/user/**").hasAuthority("participant")
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.addFilterBefore(new JwtAuthFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
package com.bruce.sams.controller;
|
||||
|
||||
import com.bruce.sams.domain.sys.User;
|
||||
import com.bruce.sams.utils.AjaxResult;
|
||||
import com.bruce.sams.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户管理控制器(仅管理员可用)
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/admin/user")
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* 批量导入用户
|
||||
*
|
||||
* @param users 用户列表
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/import")
|
||||
public AjaxResult importUsers(@RequestBody List<User> users) {
|
||||
userService.importUsers(users);
|
||||
return AjaxResult.success("用户导入成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户列表(可按学号、用户名、邮箱搜索)
|
||||
*
|
||||
* @param keyword 关键字(可选)
|
||||
* @return 用户列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public AjaxResult listUsers(@RequestParam(required = false) String keyword) {
|
||||
return AjaxResult.success("查询成功", userService.listUsers(keyword));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户信息(角色、状态、密码)
|
||||
*
|
||||
* @param user 用户对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/update")
|
||||
public AjaxResult updateUser(@RequestBody User user) {
|
||||
userService.updateUser(user);
|
||||
return AjaxResult.success("用户信息更新成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户(逻辑删除)
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/delete/{userId}")
|
||||
public AjaxResult deleteUser(@PathVariable Long userId) {
|
||||
userService.deleteUser(userId);
|
||||
return AjaxResult.success("用户删除成功");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.bruce.sams.controller;
|
||||
|
||||
import com.bruce.sams.domain.sys.User;
|
||||
import com.bruce.sams.utils.AjaxResult;
|
||||
import com.bruce.sams.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 普通用户修改个人信息控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/user/profile")
|
||||
public class UserProfileController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
@PutMapping("/change-password")
|
||||
public AjaxResult changePassword(@RequestAttribute Long userId,
|
||||
@RequestParam String oldPassword,
|
||||
@RequestParam String newPassword) {
|
||||
userService.changePassword(userId, oldPassword, newPassword);
|
||||
return AjaxResult.success("密码修改成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改个人信息
|
||||
*/
|
||||
@PutMapping("/update")
|
||||
public AjaxResult updateProfile(@RequestAttribute Long userId, @RequestBody User user) {
|
||||
userService.updateProfile(userId, user);
|
||||
return AjaxResult.success("个人信息更新成功");
|
||||
}
|
||||
}
|
||||
|
|
@ -22,27 +22,25 @@ public class JwtAuthFilter extends OncePerRequestFilter {
|
|||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
// 获取请求头中的 Authorization 令牌
|
||||
String token = request.getHeader("Authorization");
|
||||
|
||||
// 判断令牌是否存在且以 "Bearer " 开头
|
||||
if (token != null && token.startsWith("Bearer ")) {
|
||||
token = token.substring(7); // 去掉 "Bearer " 前缀
|
||||
token = token.substring(7);
|
||||
try {
|
||||
// 解析 JWT 令牌
|
||||
String schoolId = TokenUtil.getSubjectFromToken(token);
|
||||
Long userId = TokenUtil.getUserIdFromToken(token);
|
||||
String role = TokenUtil.getRoleFromToken(token);
|
||||
|
||||
// 设置认证信息
|
||||
// 将 userId 存入 request,供 Controller 直接使用
|
||||
request.setAttribute("userId", userId);
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new UsernamePasswordAuthenticationToken(schoolId, null, null));
|
||||
new UsernamePasswordAuthenticationToken(userId, null, null));
|
||||
} catch (Exception e) {
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Token");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 继续执行过滤器链
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
package com.bruce.sams.service;
|
||||
|
||||
import com.bruce.sams.domain.sys.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserService {
|
||||
|
||||
/**
|
||||
* 批量导入用户
|
||||
*
|
||||
* @param users 用户列表
|
||||
*/
|
||||
void importUsers(List<User> users);
|
||||
|
||||
/**
|
||||
* 查询用户列表(学号、用户名、邮箱)
|
||||
*
|
||||
* @param keyword 关键字
|
||||
* @return 用户列表
|
||||
*/
|
||||
List<User> listUsers(String keyword);
|
||||
|
||||
/**
|
||||
* 更新用户信息(角色、状态、密码)
|
||||
*
|
||||
* @param user 用户对象
|
||||
*/
|
||||
void updateUser(User user);
|
||||
|
||||
/**
|
||||
* 用户修改密码
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param oldPassword 旧密码
|
||||
* @param newPassword 新密码
|
||||
*/
|
||||
void changePassword(Long userId, String oldPassword, String newPassword);
|
||||
|
||||
/**
|
||||
* 用户修改个人信息(昵称、邮箱、头像)
|
||||
*
|
||||
* @param userId 用户ID(从 JWT 获取)
|
||||
* @param updatedUser 用户提交的新信息(昵称、邮箱、头像)
|
||||
*/
|
||||
void updateProfile(Long userId, User updatedUser);
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
void deleteUser(Long userId);
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
package com.bruce.sams.service.impl;
|
||||
|
||||
import com.bruce.sams.domain.entity.LoginRequest;
|
||||
import com.bruce.sams.domain.sys.User;
|
||||
import com.bruce.sams.exception.AccountDisabledException;
|
||||
import com.bruce.sams.exception.PasswordIncorrectException;
|
||||
import com.bruce.sams.exception.UserNotFoundException;
|
||||
import com.bruce.sams.mapper.SysRoleMapper;
|
||||
import com.bruce.sams.mapper.SysUserMapper;
|
||||
import com.bruce.sams.domain.sys.User;
|
||||
import com.bruce.sams.service.AuthService;
|
||||
import com.bruce.sams.utils.PasswordUtil;
|
||||
import com.bruce.sams.utils.TokenUtil;
|
||||
import com.bruce.sams.service.AuthService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
|
@ -62,6 +62,6 @@ public class AuthServiceImpl implements AuthService {
|
|||
String role = roleMapper.findByRoleId(user.getRoleId()).getRoleKey();
|
||||
|
||||
// 生成 JWT 令牌
|
||||
return TokenUtil.generateToken(user.getSchoolId(), role);
|
||||
return TokenUtil.generateToken(user);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
package com.bruce.sams.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.bruce.sams.domain.sys.User;
|
||||
import com.bruce.sams.exception.PasswordIncorrectException;
|
||||
import com.bruce.sams.exception.UserNotFoundException;
|
||||
import com.bruce.sams.mapper.SysUserMapper;
|
||||
import com.bruce.sams.service.UserService;
|
||||
import com.bruce.sams.utils.PasswordUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl extends ServiceImpl<SysUserMapper, User>
|
||||
implements UserService {
|
||||
|
||||
@Autowired
|
||||
private SysUserMapper userMapper;
|
||||
|
||||
/**
|
||||
* 批量导入用户
|
||||
*
|
||||
* @param users 用户列表
|
||||
*/
|
||||
public void importUsers(List<User> users) {
|
||||
for (User user : users) {
|
||||
// 加密用户密码(默认密码123456)
|
||||
if (user.getPassword() == null || user.getPassword().isEmpty()) {
|
||||
user.setPassword(PasswordUtil.encode("123456")); // 默认密码
|
||||
} else {
|
||||
user.setPassword(PasswordUtil.encode(user.getPassword()));
|
||||
}
|
||||
userMapper.insert(user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户列表(学号、用户名、邮箱)
|
||||
*
|
||||
* @param keyword 关键字
|
||||
* @return 用户列表
|
||||
*/
|
||||
public List<User> listUsers(String keyword) {
|
||||
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (keyword != null && !keyword.isEmpty()) {
|
||||
queryWrapper.like(User::getUserName, keyword)
|
||||
.or().like(User::getSchoolId, keyword)
|
||||
.or().like(User::getEmail, keyword);
|
||||
}
|
||||
return userMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户信息(角色、状态、密码)
|
||||
*
|
||||
* @param user 用户对象
|
||||
*/
|
||||
public void updateUser(User user) {
|
||||
// 如果要修改密码,先加密
|
||||
if (user.getPassword() != null && !user.getPassword().isEmpty()) {
|
||||
user.setPassword(PasswordUtil.encode(user.getPassword()));
|
||||
}
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用户修改密码
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param oldPassword 旧密码
|
||||
* @param newPassword 新密码
|
||||
*/
|
||||
public void changePassword(Long userId, String oldPassword, String newPassword) {
|
||||
// 获取用户
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user == null) {
|
||||
throw new UserNotFoundException();
|
||||
}
|
||||
|
||||
// 验证旧密码
|
||||
if (!PasswordUtil.matches(oldPassword, user.getPassword())) {
|
||||
throw new PasswordIncorrectException();
|
||||
}
|
||||
|
||||
// 更新新密码(加密存储)
|
||||
user.setPassword(PasswordUtil.encode(newPassword));
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户修改个人信息(昵称、邮箱、头像)
|
||||
*
|
||||
* @param userId 用户ID(从 JWT 获取)
|
||||
* @param updatedUser 用户提交的新信息(昵称、邮箱、头像)
|
||||
*/
|
||||
public void updateProfile(Long userId, User updatedUser) {
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user == null) {
|
||||
throw new UserNotFoundException();
|
||||
}
|
||||
|
||||
// 仅允许修改部分字段
|
||||
user.setNickName(updatedUser.getNickName());
|
||||
user.setEmail(updatedUser.getEmail());
|
||||
user.setAvatar(updatedUser.getAvatar());
|
||||
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
public void deleteUser(Long userId) {
|
||||
userMapper.deleteById(userId);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.bruce.sams.utils;
|
||||
|
||||
import com.bruce.sams.domain.sys.User;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
|
|
@ -23,15 +24,14 @@ public class TokenUtil {
|
|||
/**
|
||||
* 生成JWT令牌
|
||||
*
|
||||
* @param username 需要包含的声明
|
||||
* @param role 令牌主体
|
||||
* @param user 用户信息
|
||||
* @return 生成的JWT字符串
|
||||
*/
|
||||
public static String generateToken(String username , String role) {
|
||||
public static String generateToken(User user) {
|
||||
HashMap<String, Object> claims = new HashMap<>();
|
||||
claims.put("role", role);
|
||||
claims.put("role", user.getRoleId());
|
||||
return Jwts.builder()
|
||||
.subject(username)
|
||||
.subject(String.valueOf(user.getUserId()))
|
||||
.claims(claims)
|
||||
.issuedAt(new Date())
|
||||
.expiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
|
||||
|
|
@ -54,7 +54,7 @@ public class TokenUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* 从令牌中获取用户名
|
||||
* 从令牌中获取token主体
|
||||
*
|
||||
* @param token JWT字符串
|
||||
* @return 令牌中的subject
|
||||
|
|
@ -63,6 +63,16 @@ public class TokenUtil {
|
|||
return parseToken(token).getSubject();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从令牌中获取用户ID
|
||||
*
|
||||
* @param token JWT字符串
|
||||
* @return 令牌中的用户ID
|
||||
*/
|
||||
public static Long getUserIdFromToken(String token) {
|
||||
return Long.parseLong(getSubjectFromToken(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从令牌中获取角色信息
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue