v0.1.5 优化TokenUtil 完善用户操作部分

v0.1
bruce 2025-02-13 16:54:37 +08:00
parent e7931c8b93
commit 0ca2a5317b
8 changed files with 309 additions and 19 deletions

View File

@ -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);

View File

@ -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("用户删除成功");
}
}

View File

@ -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("个人信息更新成功");
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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));
}
/**
*
*