Next.js 쿠키 삭제가 안 되는 문제

GwangSoo·2025년 5월 7일
0

개인공부

목록 보기
25/34
post-thumbnail

Next.js 프로젝트를 진행하면서 로그인 후 받은 유저 토큰을 httpOnly 쿠키에서 관리하게 되었다.

토큰 관련 사진

유저 인증을 위해 이 쿠키를 활용했는데, 로그아웃 시 쿠키 삭제를 위해 아래 코드를 작성했다.

"use server";

import { cookies } from "next/headers";

export const removeAuth = async () => {
  const cookieStorage = await cookies();
  cookieStorage.delete("accessToken");
  cookieStorage.delete("refreshToken");
};

하지만 배포 후 서버에서 받은 쿠키가 삭제되지 않는 문제가 발생했다.

문제의 원인

로그인을 카카오와 구글 소셜 로그인을 통해 진행했고, 서버에서는 소셜 로그인 성공 후 다음과 같은 방식으로 쿠키를 설정하여 리다이렉트했다.

  • 도메인: .nebula-ai.kr
  • 경로(path): /
  • SameSite: none
  • Secure: true

해결 방법

따라서 쿠키 삭제 시에도 정확한 옵션을 명시해줘야 했다.

아래처럼 옵션을 넣어서 작성하니 정상적으로 쿠키가 삭제되는 것을 확인했다.

"use server";

import { cookies } from "next/headers";

export const removeAuth = async () => {
  const cookieStorage = await cookies();
  cookieStorage.delete({
    name: "accessToken",
    domain: ".nebula-ai.kr",
    path: "/",
    sameSite: "none",
    secure: true,
  });
  cookieStorage.delete({
    name: "refreshToken",
    domain: ".nebula-ai.kr",
    path: "/",
    sameSite: "none",
    secure: true,
  });
};

왜 name만 지정하면 삭제되지 않을까?

Next.js의 쿠키 관련 타입 정의를 통해 원인을 분석해보자.

Next.js에서는 쿠키 관리로 RequestCookiesResponseCookies 클래스를 사용한다.

declare class RequestCookies {
  delete(names: string | string[]): boolean | boolean[];
}

declare class ResponseCookies {
  delete(...args: [key: string] | [options: Omit<ResponseCookie, 'value' | 'expires'>]): this;
}

wicg에서 제공하는 Cookie Store API를 기반으로 한 타입 정의이며, 특히 delete(name)을 호출했을 때의 기본 동작은 다음과 같다.

delete(name)의 기본 동작

옵션delete(name) 호출 시 기본값실제 설정한 쿠키 옵션
domainnull (호스트 전용).nebula-ai.kr
path//
securetruetrue
sameSitestrictnone

여기서 domain이 다르고, sameSite 속성이 다르기 때문에 쿠키가 삭제되지 않았던 것이다.

호스트 전용 쿠키란?

  • domain 속성이 없는 쿠키로, 정확한 호스트에만 전송되는 쿠키이다.
  • domain 속성이 있으면 서브 도메인에도 전송된다. (예: example.com, app.example.com)

즉, 기본 delete(name)호스트 전용 쿠키만 삭제 가능하므로, 명시적 옵션을 넣어줘야 했다.

next/headers의 cookies 타입 분석

Next.js의 cookies() 메서드는 어떤 타입을 리턴하는지 살펴보았다.

export type ReadonlyRequestCookies = Omit<RequestCookies, 'set' | 'clear' | 'delete'> & Pick<ResponseCookies, 'set' | 'delete'>;

export declare function cookies(): Promise<ReadonlyRequestCookies>;

이 타입은 다음과 같은 특성을 가지고 있다.

  • RequestCookies에서 쿠키 조작(set, clear, delete)을 빼고,
  • ResponseCookies의 set, delete만 추가.

Next.js 개발자가 의도적으로 쿠키를 Readonly하게 관리하면서 부작용을 방지하기 위함이라고 판단된다.

마무리하며

이번 디버깅을 통해 Next.js의 쿠키 처리 과정을 깊이 이해할 수 있었으며, 정확한 쿠키 삭제 방법을 알게 되었다.

참고 자료

0개의 댓글