增加同意验证,但是没有成功

This commit is contained in:
2025-08-07 10:18:28 +08:00
parent d2e479b9f8
commit ad85efaa74
7 changed files with 167 additions and 57 deletions

View File

@@ -27,7 +27,8 @@ public class SecurityConfig {
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll() .requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN") .requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasAnyRole("USER", "ADMIN") // .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.requestMatchers("/user/**").permitAll()
.anyRequest().authenticated() .anyRequest().authenticated()
); );
return http.build(); return http.build();

View File

@@ -0,0 +1,20 @@
package com.onekeycall.videotablet.config;
import com.onekeycall.videotablet.interceptor.TokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//@Configuration
//public class WebConfig implements WebMvcConfigurer {
// @Autowired
// private TokenInterceptor tokenInterceptor;
//
// @Override
// public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(tokenInterceptor)
// .addPathPatterns("/user/**") // 保护用户相关端点
// .excludePathPatterns("/public/**"); // 开放登录注册
// }
//}

View File

@@ -48,8 +48,8 @@ public class LoginController {
@PostMapping("/login") @PostMapping("/login")
public ResponseEntity<?> login( public ResponseEntity<?> login(
@RequestParam(value = "user_id") String userId, @RequestParam String password, @RequestHeader("Device-ID") String deviceId,
@RequestParam(value = "device_id", required = false) String deviceId) { @RequestParam(value = "user_id") String userId, @RequestParam String password) {
// 1. 创建认证令牌 // 1. 创建认证令牌
Authentication authenticationToken = new UsernamePasswordAuthenticationToken(userId, password); Authentication authenticationToken = new UsernamePasswordAuthenticationToken(userId, password);
@@ -57,8 +57,8 @@ public class LoginController {
Authentication authentication = authenticationManager.authenticate(authenticationToken); Authentication authentication = authenticationManager.authenticate(authenticationToken);
// 3. 认证成功后生成 JWT // 3. 认证成功后生成 JWT
UserDetails userDetails = (UserDetails) authentication.getPrincipal(); User userDetails = (User) authentication.getPrincipal();
TokenPair tokenPair = jwtUtil.generateTokenPair(userDetails.getUsername(), deviceId); TokenPair tokenPair = jwtUtil.generateTokenPair(userDetails.getUserId(), deviceId);
// 4. 返回 Token // 4. 返回 Token
return ResponseEntity.ok(Collections.singletonMap("token", tokenPair.toMap())); return ResponseEntity.ok(Collections.singletonMap("token", tokenPair.toMap()));

View File

@@ -8,10 +8,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/user") @RequestMapping("/user")
@@ -32,52 +29,47 @@ public class UserPasswordController {
@PostMapping("/phone_set_password") @PostMapping("/phone_set_password")
public Result setPasswordByPhone( public Result setPasswordByPhone(
HttpServletRequest request, @RequestParam(value = "user_id") String userId, @RequestHeader("Authorization") String authHeader, @RequestHeader("Device-ID") String deviceId,
@RequestParam String password, @RequestParam(value = "verify_password") String verifyPassword, @RequestParam(value = "user_id") String userId,
@RequestParam(value = "device_id") String deviceId) { @RequestParam String password, @RequestParam(value = "verify_password") String verifyPassword) {
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) { if (authHeader == null || !authHeader.startsWith("Bearer ")) {
return Result.error().message("Authorization header is incorrect");
}
if (!StringUtils.equals(password, verifyPassword)) {
return Result.error().message("password is not same");
}
String token = authHeader.substring(7); // 提取真正的Token String token = authHeader.substring(7); // 提取真正的Token
if (StringUtils.equals(password, verifyPassword)) {
if (jwtUtil.validateAccessToken(userId, token, deviceId)) { if (jwtUtil.validateAccessToken(userId, token, deviceId)) {
userService.setPasswordByUserId(userId, password); userService.setPasswordByUserId(userId, password);
return Result.ok().message("set password success"); return Result.ok().message("set password success");
} else { } else {
return Result.error().message("token is not same"); return Result.error().message("token is not same");
} }
} else {
return Result.error().message("password is not same");
}
} else {
return Result.error().message("Authorization header is incorrect");
}
} }
@PostMapping("/change_password") @PostMapping("/change_password")
public Result changePassword( public Result changePassword(
HttpServletRequest request, @RequestHeader("Authorization") String authHeader, @RequestHeader("Device-ID") String deviceId,
@RequestParam(value = "user_id") String userId, @RequestParam(value = "user_id") String userId, @RequestParam(value = "old_password") String oldPassword,
@RequestParam(value = "old_password") String oldPassword, @RequestParam String password, @RequestParam(value = "verify_password") String verifyPassword) {
@RequestParam String password, @RequestParam(value = "verify_password") String verifyPassword, if (authHeader == null || !authHeader.startsWith("Bearer ")) {
@RequestParam(value = "device_id") String deviceId) { return Result.error().message("Authorization header is incorrect");
String authHeader = request.getHeader("Authorization"); }
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7); String token = authHeader.substring(7);
if (StringUtils.equals(password, verifyPassword)) { if (!StringUtils.equals(password, verifyPassword)) {
if (!oldPassword.equals(password)) { return Result.error().message("password is not same");
}
if (oldPassword.equals(password)) {
return Result.error().message("The old password and the new password are the same");
}
if (jwtUtil.validateAccessToken(userId, token, deviceId)) { if (jwtUtil.validateAccessToken(userId, token, deviceId)) {
return userService.changePassword(userId, oldPassword, password); return userService.changePassword(userId, oldPassword, password);
} else { } else {
return Result.error().message("token is not same"); return Result.error().message("token is not same");
} }
} else {
return Result.error().message("The old password and the new password are the same");
}
} else {
return Result.error().message("password is not same");
}
} else {
return Result.error().message("Authorization header is incorrect");
}
} }
} }

View File

@@ -0,0 +1,34 @@
package com.onekeycall.videotablet.entity;
import jakarta.persistence.*;
import lombok.Getter;
import java.util.Date;
@Getter
@Entity
@Table(name = "devices_sn")
public class DeviceInfo {
@Id
@Column(name = "sn", unique = true, nullable = false)
private String sn;
@Column(name = "device_model", nullable = false)
private String device_model;
@Column(name = "device_alias")
private String deviceAlias;
@Column(name = "user_id")
private String userId;
@Column(name = "bind_phone")
private String bind_phone;
@Column(name = "add_time", nullable = false)
private Date add_time;
@Column(name = "activation_time")
private Date activation_time;
}

View File

@@ -25,7 +25,7 @@ public class User implements UserDetails {
@Column(name = "user_id", unique = true, nullable = false) @Column(name = "user_id", unique = true, nullable = false)
private String userId; private String userId;
@Column(unique = true) @Column
private String nickname; private String nickname;
@Column() @Column()
@@ -37,13 +37,13 @@ public class User implements UserDetails {
@Column(name = "create_time",unique = true, nullable = false) @Column(name = "create_time",unique = true, nullable = false)
private Date creatTime; private Date creatTime;
@Column(name = "last_login_time", unique = true, nullable = false) @Column(name = "last_login_time")
private Date lastLoginTime; private Date lastLoginTime;
@Column(name = "update_time", unique = true, nullable = false) @Column(name = "update_time")
private Date updateTime; private Date updateTime;
@Column(name = "device_id", unique = true, nullable = false) @Column(name = "device_id", nullable = false)
private String deviceId; private String deviceId;
@Override @Override

View File

@@ -0,0 +1,63 @@
package com.onekeycall.videotablet.interceptor;
import com.onekeycall.videotablet.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Autowired
private JwtUtil jwtUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1. 获取并校验Authorization头
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing or invalid Authorization header");
return false;
}
String token = authHeader.substring(7);
// 2. 获取设备ID强制要求客户端传递
String deviceId = request.getHeader("Device-ID");
if (deviceId == null || deviceId.isEmpty()) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Device-ID header is required");
return false;
}
try {
// 3. 解析Token基础信息
Claims claims = jwtUtil.parseToken(token);
// 4. 验证Token类型必须为ACCESS
String tokenType = claims.get("type", String.class);
if (!"ACCESS".equals(tokenType)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid token type");
return false;
}
// 5. 验证设备ID绑定
String tokenDeviceId = claims.get("deviceId", String.class);
if (!deviceId.equals(tokenDeviceId)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Device binding mismatch");
return false;
}
// 6. 传递用户信息到后续流程
request.setAttribute("userId", claims.getSubject());
request.setAttribute("deviceId", deviceId);
return true;
} catch (Exception e) {
// 7. 统一异常处理
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token validation failed: " + e.getMessage());
return false;
}
}
}