梳理登录token鉴权功能
This commit is contained in:
parent
1dbfcfd0f2
commit
91db1899e0
@ -75,4 +75,4 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,13 +56,13 @@ public class AuthController {
|
||||
public static class LoginRequest {
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
|
||||
@NotBlank(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String captcha;
|
||||
|
||||
|
||||
@NotBlank(message = "验证码Key不能为空")
|
||||
private String captchaKey;
|
||||
|
||||
@ -83,7 +83,7 @@ public class AuthController {
|
||||
public static class ChangePasswordRequest {
|
||||
@NotBlank(message = "原密码不能为空")
|
||||
private String oldPassword;
|
||||
|
||||
|
||||
@NotBlank(message = "新密码不能为空")
|
||||
private String newPassword;
|
||||
|
||||
@ -103,18 +103,18 @@ public class AuthController {
|
||||
try {
|
||||
// 生成验证码
|
||||
CaptchaUtils.CaptchaResult captchaResult = captchaUtils.generateCaptcha();
|
||||
|
||||
|
||||
// 生成验证码Key
|
||||
String captchaKey = UUID.randomUUID().toString();
|
||||
|
||||
|
||||
// 注意:验证码应当存储在会话中或其他存储中,此处省略存储步骤
|
||||
// 在实际应用中,可以使用Session或其他方式存储验证码
|
||||
|
||||
|
||||
Map<String, String> result = new HashMap<>();
|
||||
result.put("captchaKey", captchaKey);
|
||||
result.put("captchaImage", captchaResult.getImageBase64());
|
||||
result.put("code", captchaResult.getCode()); // 临时方案:直接返回验证码(生产环境不建议)
|
||||
|
||||
|
||||
return Result.success(result);
|
||||
} catch (Exception e) {
|
||||
log.error("生成验证码失败: {}", e.getMessage(), e);
|
||||
@ -133,7 +133,7 @@ public class AuthController {
|
||||
// 注意:在实际应用中,应该从会话或其他存储中获取验证码进行验证
|
||||
// 此处简化处理,假设验证码已通过(实际应用中需要实现验证逻辑)
|
||||
// 如果使用了临时方案,可以从前端传回验证码进行比对
|
||||
|
||||
|
||||
// 进行身份认证
|
||||
Authentication authentication = authenticationManager.authenticate(
|
||||
new UsernamePasswordAuthenticationToken(
|
||||
@ -144,16 +144,16 @@ public class AuthController {
|
||||
AppUser user=appUserService.findByUsername(loginRequest.getUsername());
|
||||
// 设置认证信息到安全上下文
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
||||
|
||||
// 生成JWT Token
|
||||
String token = jwtUtils.generateToken(user.getUsername(),user.getId());
|
||||
|
||||
String token = jwtUtils.generateToken(user.getUsername(),user.getId());
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("token", token);
|
||||
result.put("userInfo", user);
|
||||
|
||||
|
||||
return Result.success(result);
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("用户登录失败: {}", e.getMessage(), e);
|
||||
return Result.error("登录失败: " + e.getMessage());
|
||||
@ -172,15 +172,15 @@ public class AuthController {
|
||||
String token = request.getHeader(Constants.JWT_HEADER);
|
||||
if (token != null && token.startsWith(Constants.JWT_PREFIX)) {
|
||||
token = token.substring(Constants.JWT_PREFIX.length());
|
||||
|
||||
|
||||
// 注意:在实际应用中,应该实现Token失效机制
|
||||
// 可以考虑使用短期Token或其他方式实现Token失效
|
||||
// 此处省略Token黑名单实现
|
||||
}
|
||||
|
||||
|
||||
// 清除安全上下文
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
|
||||
return Result.success();
|
||||
} catch (Exception e) {
|
||||
log.error("用户登出失败: {}", e.getMessage(), e);
|
||||
@ -198,11 +198,11 @@ public class AuthController {
|
||||
String token = request.getHeader(Constants.JWT_HEADER);
|
||||
if (token != null && token.startsWith(Constants.JWT_PREFIX)) {
|
||||
token = token.substring(Constants.JWT_PREFIX.length());
|
||||
String username = jwtUtils.getUsernameFromToken(token);
|
||||
String username = jwtUtils.getUsernameFromToken(token);
|
||||
AppUser userInfo = appUserService.findByUsername(username);
|
||||
return Result.success(userInfo);
|
||||
}
|
||||
|
||||
|
||||
return Result.unauthorized();
|
||||
} catch (Exception e) {
|
||||
log.error("获取用户信息失败: {}", e.getMessage(), e);
|
||||
@ -222,7 +222,7 @@ public class AuthController {
|
||||
if (token != null && token.startsWith(Constants.JWT_PREFIX)) {
|
||||
token = token.substring(Constants.JWT_PREFIX.length());
|
||||
String username = jwtUtils.getUsernameFromToken(token);
|
||||
|
||||
|
||||
boolean success = appUserService.changePassword(username, request.getOldPassword(), request.getNewPassword());
|
||||
if (success) {
|
||||
return Result.success();
|
||||
@ -230,29 +230,37 @@ public class AuthController {
|
||||
return Result.error("原密码错误");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Result.unauthorized();
|
||||
} catch (Exception e) {
|
||||
log.error("修改密码失败: {}", e.getMessage(), e);
|
||||
return Result.error("修改密码失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/refreshToken")
|
||||
public Result<String> refreshToken(@RequestBody Map<String, String> params) {
|
||||
String refreshToken = params.get("refreshToken");
|
||||
|
||||
if (refreshToken == null || refreshToken.trim().isEmpty()) {
|
||||
return Result.error("刷新令牌不能为空");
|
||||
}
|
||||
// 验证refreshToken的有效性并获取用户信息
|
||||
String username = jwtUtils.getUsernameFromToken(refreshToken);
|
||||
if (username != null) {
|
||||
AppUser user = appUserService.findByUsername(username);
|
||||
// 生成新的token
|
||||
return Result.success(jwtUtils.generateToken(user.getUsername(), user.getId()));
|
||||
|
||||
try {
|
||||
String username = jwtUtils.getUsernameFromToken(refreshToken);
|
||||
|
||||
if (username != null && jwtUtils.validateToken(refreshToken, username)) {
|
||||
AppUser user = appUserService.findByUsername(username);
|
||||
String newAccessToken = jwtUtils.generateRefreshToken(user.getUsername(), user.getId());
|
||||
return Result.success(newAccessToken);
|
||||
} else {
|
||||
return Result.error("刷新令牌已失效");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("刷新 Token 失败: {}", e.getMessage());
|
||||
return Result.error("刷新 Token 失败");
|
||||
}
|
||||
return Result.error("无效的刷新令牌");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ public class JwtUtils {
|
||||
@Value("${spring.security.jwt.expiration-ms}")
|
||||
private Long expirationMs;
|
||||
|
||||
@Value("${spring.security.jwt.refresh-expiration-ms}")
|
||||
private Long refreshExpirationMs;
|
||||
|
||||
/**
|
||||
* 生成JWT令牌
|
||||
*
|
||||
@ -62,6 +65,33 @@ public class JwtUtils {
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建带刷新时间的 Token
|
||||
*/
|
||||
private String createRefreshToken(Map<String, Object> claims, String subject) {
|
||||
Date now = new Date();
|
||||
Date expiryDate = new Date(now.getTime() + refreshExpirationMs);
|
||||
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setSubject(subject)
|
||||
.setIssuedAt(now)
|
||||
.setExpiration(expiryDate)
|
||||
.signWith(getSigningKey(), SignatureAlgorithm.HS512)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Refresh Token
|
||||
*/
|
||||
public String generateRefreshToken(String username, String userId) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", userId);
|
||||
claims.put("username", username);
|
||||
return createRefreshToken(claims, username);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从JWT令牌中获取用户名
|
||||
*
|
||||
@ -165,4 +195,4 @@ public class JwtUtils {
|
||||
public interface ClaimsResolver<T> {
|
||||
T resolve(Claims claims);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ spring:
|
||||
jwt:
|
||||
enabled: ${JWT_ENABLED:true} # 控制是否启用JWT认证
|
||||
secret: ${JWT_SECRET:YourJWTSecretKeyForStdProjectBackendApplicationWhichIsVeryLongAndSecure2024!@#$%^&*()}
|
||||
expiration-ms: ${JWT_EXPIRATION:86400000} # Token 过期时间 (例如: 24小时)
|
||||
expiration-ms: ${JWT_EXPIRATION:1800000} # Token 过期时间 (例如: 24小时)
|
||||
refresh-expiration-ms: ${JWT_REFRESH_EXPIRATION:604800000} # 刷新Token过期时间 (例如: 7天)
|
||||
|
||||
mybatis-plus:
|
||||
@ -155,7 +155,7 @@ logging:
|
||||
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl #org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
springdoc:
|
||||
swagger-ui:
|
||||
enabled: true
|
||||
|
Loading…
Reference in New Issue
Block a user