fix(web,api): fix WebSocket authentication for chat real-time connection
Some checks failed
ci/woodpecker/push/web Pipeline failed
ci/woodpecker/push/api Pipeline was successful

- Add withCredentials: true to socket.io client so session cookies are
  sent cross-origin with the WebSocket upgrade request
- Add cookie extraction in gateway extractTokenFromHandshake() as a
  fallback after auth.token, parsing all three BetterAuth session cookie
  name variants (__Secure-, bare, __Host- prefixes)
- Fix Chat.tsx useWebSocket call: use actual workspace ID from auth
  context (currentWorkspaceId ?? workspaceId) instead of user.id

Closes #534

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 05:28:47 -06:00
parent 6ac63fe755
commit c15456a779
3 changed files with 68 additions and 3 deletions

View File

@@ -89,7 +89,11 @@ export const Chat = forwardRef<ChatRef, ChatProps>(function Chat(
...(initialProjectId !== undefined && { projectId: initialProjectId }),
});
const { isConnected: isWsConnected } = useWebSocket(user?.id ?? "", "", {});
// Use the actual workspace ID for the WebSocket room subscription.
// Cookie-based auth (withCredentials) handles authentication, so no explicit
// token is needed here — pass an empty string as the token placeholder.
const workspaceId = user?.currentWorkspaceId ?? user?.workspaceId ?? "";
const { isConnected: isWsConnected } = useWebSocket(workspaceId, "", {});
const { isCommand, executeCommand } = useOrchestratorCommands();

View File

@@ -97,9 +97,12 @@ export function useWebSocket(
setConnectionError(null);
// Create socket connection
// withCredentials sends session cookies cross-origin so the gateway can
// authenticate via cookie when no explicit token is provided.
const newSocket = io(wsUrl, {
auth: { token },
query: { workspaceId },
withCredentials: true,
});
setSocket(newSocket);