From aa2375037f3fa5741f5179e9d2b139dc86fe922e Mon Sep 17 00:00:00 2001 From: ICubE01 Date: Mon, 22 Jun 2026 22:40:24 +0900 Subject: [PATCH 1/3] Fix logout URL - Refresh token cookie was not being sent due to cookie's path: `POST /api/auth/refresh` - Logout path was `POST /api/auth/logout` - Now modified to `DELETE /api/auth/refresh`, representing that the refresh token is being destroyed --- frontend/src/useAuth.tsx | 2 +- src/main/java/com/icube/sim/tichu/auth/AuthController.java | 4 +++- src/main/java/com/icube/sim/tichu/auth/SecurityConfig.java | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/useAuth.tsx b/frontend/src/useAuth.tsx index 2e023b3..88e7bee 100644 --- a/frontend/src/useAuth.tsx +++ b/frontend/src/useAuth.tsx @@ -39,7 +39,7 @@ export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const logout = async () => { try { - await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }); + await fetch('/api/auth/refresh', { method: 'DELETE', credentials: 'include' }); } catch (error) { console.error('Failed to call logout endpoint:', error); } diff --git a/src/main/java/com/icube/sim/tichu/auth/AuthController.java b/src/main/java/com/icube/sim/tichu/auth/AuthController.java index b5cfa47..3925fe0 100644 --- a/src/main/java/com/icube/sim/tichu/auth/AuthController.java +++ b/src/main/java/com/icube/sim/tichu/auth/AuthController.java @@ -37,7 +37,9 @@ public JwtResponse refresh( return new JwtResponse(jwtIssueResult.getAccessToken().toString()); } - @PostMapping("/logout") + // Mapped under /refresh (not /logout), so the refresh_token cookie, scoped to path /api/auth/refresh, + // is sent with the request. + @DeleteMapping("/refresh") public ResponseEntity<@NonNull Void> logout( @CookieValue(value = RefreshTokenCookieFactory.COOKIE_NAME, required = false) String refreshToken, HttpServletResponse response diff --git a/src/main/java/com/icube/sim/tichu/auth/SecurityConfig.java b/src/main/java/com/icube/sim/tichu/auth/SecurityConfig.java index fa89124..fe9d30b 100644 --- a/src/main/java/com/icube/sim/tichu/auth/SecurityConfig.java +++ b/src/main/java/com/icube/sim/tichu/auth/SecurityConfig.java @@ -69,7 +69,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) { .authorizeHttpRequests(c -> c .requestMatchers("/error").permitAll() .requestMatchers(HttpMethod.POST, "/api/users").permitAll() - .requestMatchers(HttpMethod.POST, "/api/auth/login", "/api/auth/refresh", "/api/auth/logout").permitAll() + .requestMatchers(HttpMethod.POST, "/api/auth/login", "/api/auth/refresh").permitAll() + .requestMatchers(HttpMethod.DELETE, "/api/auth/refresh").permitAll() .requestMatchers(HttpMethod.GET, "/api/auth/social/*/url").permitAll() .requestMatchers(HttpMethod.POST, "/api/auth/social/*/login").permitAll() .requestMatchers("/api/ws").permitAll() From 85020b3cb3b6f40723eb9d4d57ec1183035a1248 Mon Sep 17 00:00:00 2001 From: ICubE01 Date: Wed, 24 Jun 2026 20:21:01 +0900 Subject: [PATCH 2/3] Rename AuthService::logout to AuthService::destroyRefreshToken --- src/main/java/com/icube/sim/tichu/auth/AuthController.java | 2 +- src/main/java/com/icube/sim/tichu/auth/AuthService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/icube/sim/tichu/auth/AuthController.java b/src/main/java/com/icube/sim/tichu/auth/AuthController.java index 3925fe0..6a1bda7 100644 --- a/src/main/java/com/icube/sim/tichu/auth/AuthController.java +++ b/src/main/java/com/icube/sim/tichu/auth/AuthController.java @@ -44,7 +44,7 @@ public JwtResponse refresh( @CookieValue(value = RefreshTokenCookieFactory.COOKIE_NAME, required = false) String refreshToken, HttpServletResponse response ) { - authService.logout(refreshToken); + authService.destroyRefreshToken(refreshToken); response.addCookie(refreshTokenCookieFactory.createExpired()); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/com/icube/sim/tichu/auth/AuthService.java b/src/main/java/com/icube/sim/tichu/auth/AuthService.java index 44bc15c..afca8ab 100644 --- a/src/main/java/com/icube/sim/tichu/auth/AuthService.java +++ b/src/main/java/com/icube/sim/tichu/auth/AuthService.java @@ -64,7 +64,7 @@ public JwtIssueResult refreshTokens(String oldRefreshToken) { return issueTokens(user); } - public void logout(String refreshToken) { + public void destroyRefreshToken(String refreshToken) { if (refreshToken == null) { return; } From 5e96d97036365134e79b7332c4fea29a11b1b8c0 Mon Sep 17 00:00:00 2001 From: ICubE01 Date: Wed, 24 Jun 2026 22:10:56 +0900 Subject: [PATCH 3/3] Rename MeResponse to UserAuthDto --- frontend/src/types.ts | 2 +- frontend/src/useAuth.tsx | 10 +++++----- .../java/com/icube/sim/tichu/auth/AuthController.java | 4 ++-- .../tichu/auth/{MeResponse.java => UserAuthDto.java} | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) rename src/main/java/com/icube/sim/tichu/auth/{MeResponse.java => UserAuthDto.java} (89%) diff --git a/frontend/src/types.ts b/frontend/src/types.ts index da72c1c..66b8bd3 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -14,7 +14,7 @@ export interface ErrorDto { export type Role = 'USER' | 'ADMIN' | 'BOT'; -export interface MeResponse { +export interface UserAuthDto { id: number; name: string; role: Role; diff --git a/frontend/src/useAuth.tsx b/frontend/src/useAuth.tsx index 88e7bee..be31661 100644 --- a/frontend/src/useAuth.tsx +++ b/frontend/src/useAuth.tsx @@ -1,10 +1,10 @@ import React, { createContext, useState, useContext, useEffect } from 'react'; -import { JwtResponse, MeResponse } from "@/types.ts"; +import { JwtResponse, UserAuthDto } from "@/types.ts"; interface Auth { ready: boolean; accessToken: string | null; - user: MeResponse | null; + user: UserAuthDto | null; impersonating: string | null; login: (token: string) => Promise; logout: () => Promise; @@ -18,15 +18,15 @@ const AuthContext = createContext(null); export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const [ready, setReady] = useState(false); const [accessToken, setAccessToken] = useState(null); - const [user, setUser] = useState(null); + const [user, setUser] = useState(null); const [impersonating, setImpersonating] = useState(null); - const fetchUserInfo = async (token: string): Promise => { + const fetchUserInfo = async (token: string): Promise => { const response = await fetch('/api/auth/me', { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to fetch user info'); } - return await response.json() as MeResponse; + return await response.json() as UserAuthDto; }; const login = async (token: string) => { diff --git a/src/main/java/com/icube/sim/tichu/auth/AuthController.java b/src/main/java/com/icube/sim/tichu/auth/AuthController.java index 6a1bda7..fff12dc 100644 --- a/src/main/java/com/icube/sim/tichu/auth/AuthController.java +++ b/src/main/java/com/icube/sim/tichu/auth/AuthController.java @@ -50,9 +50,9 @@ public JwtResponse refresh( } @GetMapping("/me") - public MeResponse getMe() { + public UserAuthDto getMe() { var user = authService.getCurrentUser(); - return new MeResponse(user.getId(), user.getName(), user.getRole()); + return new UserAuthDto(user.getId(), user.getName(), user.getRole()); } @GetMapping("/issue/web-socket-token") diff --git a/src/main/java/com/icube/sim/tichu/auth/MeResponse.java b/src/main/java/com/icube/sim/tichu/auth/UserAuthDto.java similarity index 89% rename from src/main/java/com/icube/sim/tichu/auth/MeResponse.java rename to src/main/java/com/icube/sim/tichu/auth/UserAuthDto.java index ed6ecee..2e435be 100644 --- a/src/main/java/com/icube/sim/tichu/auth/MeResponse.java +++ b/src/main/java/com/icube/sim/tichu/auth/UserAuthDto.java @@ -6,7 +6,7 @@ @AllArgsConstructor @Getter -public class MeResponse { +public class UserAuthDto { private Long id; private String name; private Role role;