feat: 解耦认证逻辑

This commit is contained in:
2026-06-24 12:17:09 +08:00
parent 5d9f5b8ab7
commit ab2a2dbf7f
14 changed files with 332 additions and 94 deletions

View File

@@ -1,6 +1,6 @@
package com.webgame.webgamebackend.sse;
import cn.dev33.satoken.stp.StpUtil;
import com.webgame.webgamebackend.common.auth.AuthenticationProvider;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -29,29 +29,28 @@ public class SseController {
private static final long SSE_TIMEOUT_MS = 30 * 60 * 1000L;
private final SseConnectionManager connectionManager;
private final AuthenticationProvider authProvider;
@GetMapping(value = "/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter subscribe(
@RequestHeader(value = "Last-Event-ID", required = false) String lastEventId,
HttpServletResponse response) throws IOException {
// SSE 路径已排除在 SaInterceptor 之外,此处手动校验登录态
String token = StpUtil.getTokenValue();
// SSE 路径已排除在 AuthInterceptor 之外,此处手动校验登录态
String token = authProvider.getCurrentToken();
if (token == null || token.isBlank()) {
log.warn("[SSE] 缺少认证 token");
return writeAuthError(response, HttpServletResponse.SC_UNAUTHORIZED, "缺少认证信息,请先登录");
}
Object loginId = StpUtil.getLoginIdByToken(token);
if (loginId == null) {
String userId = authProvider.getUserIdByToken(token);
if (userId == null) {
log.warn("[SSE] token 无效或已过期");
return writeAuthError(response, HttpServletResponse.SC_UNAUTHORIZED, "登录已过期,请重新登录");
}
// 设置 Sa-Token 上下文,后续 StpUtil.getLoginIdAsString() 可用
StpUtil.setTokenValue(token, -1);
String userId = loginId.toString();
// 设置认证上下文,后续 getCurrentUserId() 可用
authProvider.setContextToken(token, -1);
SseEmitter emitter = new SseEmitter(SSE_TIMEOUT_MS);
String connectionId = connectionManager.register(userId, emitter);