Web Devlopment/NextJs

#24. Route 에서 Header, Cookies 사용

키모형 2025. 12. 29. 22:14
반응형

1) Route Handler에서 Header 읽기: 2가지 방법

A. NextRequest로 읽기 (가장 직관적)

  • request.headers.get("authorization")
  • 이 방식은 “지금 들어온 요청 객체”에서 바로 읽습니다.
 
export async function GET(request: NextRequest) {
  const auth = request.headers.get("authorization");
}

B. next/headers의 headers()로 읽기

  • const headerList = await headers(); headerList.get(...)
  • Next 15+에서는 headers()가 비동기(await 필요) 입니다. nextjs.org+1
  • headers()로 받은 객체는 읽기 전용입니다(설정은 응답에서 해야 함). nextjs-ko.org+1
import { headers } from "next/headers";

const headerList = await headers();
const auth = headerList.get("authorization");

Route Handler에서는 request가 이미 있으니 보통 A 방식이 더 명확하고, headers()는 request 객체가 없는(Server Component 등) 환경에서 특히 유용합니다.

 


2) Route Handler에서 Cookie 읽기/쓰기

쿠키 읽기(요청 쿠키)

  • request.cookies.get("theme")?.value
  • cookies()로도 읽을 수 있습니다(Next 15+ await 필요). nextjs.org+1

쿠키 쓰기(응답 쿠키)

쿠키는 “요청에 들어오는 것”과 “응답으로 내려주는 것”이 다릅니다.

  • 추천 방식: NextResponse를 만든 뒤 response.cookies.set(...)로 설정
    (직관적이고, 여러 쿠키/옵션 처리도 안정적)

3) 예시

import { NextRequest, NextResponse } from "next/server";
import { headers } from "next/headers";

export async function GET(request: NextRequest) {
  // (1) 요청 헤더 읽기
  const authA = request.headers.get("authorization"); // NextRequest 방식
  const authB = (await headers()).get("authorization"); // next/headers 방식 (Next 15+ await)
  console.log({ authA, authB });

  // (2) 요청 쿠키 읽기
  const theme = request.cookies.get("theme")?.value ?? "light";
  console.log({ theme });

  // (3) 응답 만들기
  const res = new NextResponse(`<h1>Profile API data</h1><p>theme=${theme}</p>`, {
    headers: {
      "content-type": "text/html; charset=utf-8",
      "x-route-name": "profile",
    },
  });

  // (4) 응답 쿠키 설정 (권장)
  res.cookies.set("resultPerPage", "20", {
    path: "/",
    maxAge: 60 * 60 * 24 * 30, // 30일
    sameSite: "lax",
  });

  res.cookies.set("theme", "dark", {
    path: "/",
    httpOnly: true,
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
  });

  return res;
}
  • 위 방식이면 굳이 headers: { "Set-Cookie": ... }를 직접 손으로 쓰지 않아도 됩니다(실수/포맷 이슈 방지).
  • headers()/cookies() 같은 Dynamic API는 Next 15+에서 비동기라는 점이 핵심입니다. nextjs.org+1

4) “Header/Cookie를 라우팅 로직에 활용”하는 실전 예시

예: 헤더/쿠키 기반으로 접근 제어(간단 인증)

export async function GET(request: NextRequest) {
  const token = request.headers.get("authorization");
  if (!token) {
    return NextResponse.json({ ok: false, message: "No Authorization" }, { status: 401 });
  }
  return NextResponse.json({ ok: true });
}
 
예: 쿠키로 사용자 설정(페이지당 노출 개수) 유지
  • /api/profile 호출 시 resultPerPage 쿠키를 심어두고,
  • 이후 다른 페이지/요청에서 request.cookies.get("resultPerPage")로 읽어서 UI/쿼리에 반영

 

쿠키 옵션 

path

  • 쿠키를 어떤 URL 경로에서 브라우저가 서버로 보낼지 범위를 정합니다.
  • Next.js에서 기본값은 '/' 입니다. nextjs.org
  • 예:
    • path: '/' → 사이트 전체 요청에 쿠키가 포함됨
    • path: '/admin' → /admin, /admin/... 요청에서만 쿠키 포함

보안/의도 측면에서 “가능한 좁게” 잡는 것이 권장됩니다. MDN Web Docs


httpOnly

  • 브라우저 JS(document.cookie)로 쿠키를 읽지 못하게 막습니다.
  • 즉, XSS로 쿠키(세션 토큰 등) 탈취 위험을 크게 줄임 → 세션/리프레시 토큰에 강력 추천입니다. nextjs.org+1
  • 주의: httpOnly여도 브라우저는 요청에 쿠키를 자동으로 실어 보내므로, CSRF 방어는 sameSite/CSRF 토큰 등과 같이 설계해야 합니다. MDN Web Docs

maxAge (초 단위)

  • 쿠키 수명(만료까지)을 “초(seconds)”로 지정합니다. nextjs.org
  • 예: maxAge: 60 * 60 → 1시간
  • 값이 없으면 “세션 쿠키(브라우저 세션 종료 시 삭제)”로 동작하는 쪽으로 이해하시면 됩니다. MDN Web Docs

expires (Date)

  • 절대 만료 시각(Date) 을 지정합니다. nextjs.org+1
  • expires와 maxAge를 둘 다 주면, 일반적으로 Max-Age가 우선 적용됩니다. MDN Web Docs
  • 실무 팁: 보통은 maxAge만 써도 충분하고(초 단위라 덜 실수), “특정 시각에 만료”가 필요하면 expires를 씁니다.

secure

  • HTTPS 요청에서만 쿠키를 전송하도록 합니다. nextjs.org+1
  • 운영(HTTPS)에서는 로그인/세션/토큰 쿠키에 거의 필수로 보시면 됩니다.
  • (참고) SameSite=None을 쓰려면 일반적으로 Secure가 함께 필요합니다. MDN Web Docs

sameSite

  • 크로스사이트 요청에서 쿠키를 보낼지 제어합니다. nextjs.org+1
  • 값:
    • 'strict' : 가장 보수적(타 사이트에서 넘어오는 요청엔 거의 안 보냄) → CSRF 방어 강함 MDN Web Docs
    • 'lax' : 기본적으로 무난(일부 top-level 이동 등은 허용) MDN Web Docs
    • 'none' : 크로스사이트에서도 보냄(3rd-party/iframe 등) → 보통 Secure 필요 MDN Web Docs
    • true/false도 지원(일반적으로 true는 strict 의미, false는 속성 미설정) nextjs.org+1

domain

  • 쿠키를 어떤 도메인(및 서브도메인) 범위에서 보낼지 결정합니다. nextjs.org+1
  • 예:
    • domain: 'example.com' → www.example.com, api.example.com 등에도 전송될 수 있음
  • 실무 팁: 정말 필요할 때만, 가능한 가장 좁게 잡는 것이 권장됩니다. MDN Web Docs+1

priority (low/medium/high)

  • 브라우저가 쿠키를 정리/삭제(저장공간 압박)할 때의 우선순위 힌트입니다. Next.js가 지원합니다. nextjs.org
  • 대부분은 기본값(설정 안 함)으로 충분합니다.

partitioned

  • “Partitioned cookie”(CHIPS) 관련 옵션으로, **3rd-party 컨텍스트에서 ‘탑레벨 사이트별로 분리 저장’**되는 쿠키입니다.
  • Next.js가 지원하며, MDN 기준으로 Partitioned 쿠키는 Secure가 필요하다는 점이 중요합니다. nextjs.org+1
  • 일반 로그인 쿠키에는 보통 안 쓰고, iframe/서드파티 시나리오에서 고려합니다.

실전 예시 2개

1) 로그인/세션 토큰(권장: HttpOnly + Secure + SameSite)

 
res.cookies.set("sid", sessionId, {
  httpOnly: true,
  secure: process.env.NODE_ENV === "production",
  sameSite: "lax",
  path: "/",
  maxAge: 60 * 60 * 24 * 7, // 7일(초)
});

2) UI 설정(클라이언트에서도 읽어야 하면 httpOnly 빼기)

res.cookies.set("theme", "dark", {
  path: "/",
  maxAge: 60 * 60 * 24 * 365, // 1년
  sameSite: "lax",
});

 

반응형