[feat]: Safari 쿠키 호환성 및 UI/UX 개선
주요 변경사항: - Safari 쿠키 호환성 개선 (SameSite=Lax, 개발 환경 Secure 제외) - Sidebar 활성 메뉴 자동 스크롤 기능 추가 - Sidebar 스크롤바 스타일링 (호버 시에만 표시) - DashboardLayout sticky 포지셔닝 적용 - IE 브라우저 차단 및 안내 페이지 추가 - 메뉴 탐색 로직 개선 (서브메뉴 우선 매칭) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -72,23 +72,26 @@ export async function GET(request: NextRequest) {
|
||||
if (refreshResponse.ok) {
|
||||
const data = await refreshResponse.json();
|
||||
|
||||
// Set new tokens
|
||||
// Set new tokens with Safari-compatible configuration
|
||||
// Safari compatibility: Secure only in production (HTTPS)
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
const accessTokenCookie = [
|
||||
`access_token=${data.access_token}`,
|
||||
'HttpOnly',
|
||||
'Secure',
|
||||
'SameSite=Strict',
|
||||
'HttpOnly', // ✅ JavaScript cannot access
|
||||
...(isProduction ? ['Secure'] : []), // ✅ HTTPS only in production (Safari fix)
|
||||
'SameSite=Lax', // ✅ CSRF protection (Lax for better compatibility)
|
||||
'Path=/',
|
||||
`Max-Age=${data.expires_in || 7200}`,
|
||||
].join('; ');
|
||||
|
||||
const refreshTokenCookie = [
|
||||
`refresh_token=${data.refresh_token}`,
|
||||
'HttpOnly',
|
||||
'Secure',
|
||||
'SameSite=Strict',
|
||||
'HttpOnly', // ✅ JavaScript cannot access
|
||||
...(isProduction ? ['Secure'] : []), // ✅ HTTPS only in production (Safari fix)
|
||||
'SameSite=Lax', // ✅ CSRF protection (Lax for better compatibility)
|
||||
'Path=/',
|
||||
'Max-Age=604800',
|
||||
'Max-Age=604800', // 7 days (longer for refresh token)
|
||||
].join('; ');
|
||||
|
||||
console.log('✅ Token auto-refreshed in auth check');
|
||||
|
||||
@@ -148,11 +148,14 @@ export async function POST(request: NextRequest) {
|
||||
};
|
||||
|
||||
// Set HttpOnly cookies for both access_token and refresh_token
|
||||
// Safari compatibility: Secure only in production (HTTPS)
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
const accessTokenCookie = [
|
||||
`access_token=${data.access_token}`,
|
||||
'HttpOnly', // ✅ JavaScript cannot access
|
||||
'Secure', // ✅ HTTPS only (production)
|
||||
'SameSite=Strict', // ✅ CSRF protection
|
||||
...(isProduction ? ['Secure'] : []), // ✅ HTTPS only in production (Safari fix)
|
||||
'SameSite=Lax', // ✅ CSRF protection (Lax for better compatibility)
|
||||
'Path=/',
|
||||
`Max-Age=${data.expires_in || 7200}`, // Use backend expiry (default 2 hours)
|
||||
].join('; ');
|
||||
@@ -160,8 +163,8 @@ export async function POST(request: NextRequest) {
|
||||
const refreshTokenCookie = [
|
||||
`refresh_token=${data.refresh_token}`,
|
||||
'HttpOnly', // ✅ JavaScript cannot access
|
||||
'Secure', // ✅ HTTPS only (production)
|
||||
'SameSite=Strict', // ✅ CSRF protection
|
||||
...(isProduction ? ['Secure'] : []), // ✅ HTTPS only in production (Safari fix)
|
||||
'SameSite=Lax', // ✅ CSRF protection (Lax for better compatibility)
|
||||
'Path=/',
|
||||
'Max-Age=604800', // 7 days (longer for refresh token)
|
||||
].join('; ');
|
||||
|
||||
@@ -49,11 +49,14 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
|
||||
// Clear both HttpOnly cookies
|
||||
// Safari compatibility: Must use same attributes as when setting cookies
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
const clearAccessToken = [
|
||||
'access_token=',
|
||||
'HttpOnly',
|
||||
'Secure',
|
||||
'SameSite=Strict',
|
||||
...(isProduction ? ['Secure'] : []), // ✅ Match login/check cookie attributes
|
||||
'SameSite=Lax', // ✅ Match login/check cookie attributes
|
||||
'Path=/',
|
||||
'Max-Age=0', // Delete immediately
|
||||
].join('; ');
|
||||
@@ -61,8 +64,8 @@ export async function POST(request: NextRequest) {
|
||||
const clearRefreshToken = [
|
||||
'refresh_token=',
|
||||
'HttpOnly',
|
||||
'Secure',
|
||||
'SameSite=Strict',
|
||||
...(isProduction ? ['Secure'] : []), // ✅ Match login/check cookie attributes
|
||||
'SameSite=Lax', // ✅ Match login/check cookie attributes
|
||||
'Path=/',
|
||||
'Max-Age=0', // Delete immediately
|
||||
].join('; ');
|
||||
|
||||
Reference in New Issue
Block a user