Skip to content
Published on

SSO 쿠키/JWT 인증 시스템 완전 가이드 — 프레임워크별 실전 시리즈 인덱스

Authors
  • Name
    Twitter

시리즈 소개 — 왜 이 시리즈를 쓰는가

웹 인증은 단순하지 않습니다. "로그인 기능 하나 만들면 되지"라고 생각하기 쉽지만, 실전에서는 다음과 같은 질문이 꼬리를 물고 나타납니다.

  • 토큰을 쿠키에 넣을까, localStorage에 넣을까?
  • JWT세션 중 무엇을 선택해야 할까?
  • HttpOnly CookieCSRF 토큰을 어떻게 조합할까?
  • SSO(Single Sign-On) 환경에서 여러 서비스 간 인증 상태를 어떻게 공유할까?
  • Access Token 갱신은 프론트엔드에서 하나, 백엔드에서 하나?
  • CORScredentials 설정은 왜 항상 삽질을 유발할까?

이 질문들의 정답은 프레임워크마다 다릅니다. Spring Boot의 SecurityFilterChain과 Django의 SessionMiddleware는 기본 전략부터 다르고, React SPA와 Next.js SSR은 쿠키를 다루는 방식 자체가 다릅니다. 공식 문서만으로는 전체 그림을 그리기 어렵습니다.

이 시리즈는 인증 시스템의 전체 지도를 먼저 펼친 뒤, 프레임워크별로 실전 코드를 구현하는 구성입니다.

시리즈가 다루는 범위:

  • SSO / OAuth 2.0 / OIDC 프로토콜의 동작 원리
  • 쿠키 기반 인증과 JWT 기반 인증의 차이, 장단점, 하이브리드 전략
  • 브라우저 저장소(Cookie, localStorage, sessionStorage, Memory)별 보안 특성
  • CORS + Credential 전송의 정확한 설정법
  • Spring Boot, Django, React, Next.js 각 프레임워크에서의 실전 구현
  • 여러 프레임워크를 조합한 하이브리드 아키텍처 설계

인증 흐름 전체 지도

인증 시스템의 전체 흐름을 한눈에 파악하겠습니다. 아래는 SSO/OIDC 기반 로그인부터 토큰 갱신, 로그아웃까지의 전체 과정입니다.

로그인 흐름 (Login Flow)

┌──────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────┐
Browser  │     │  Frontend    │     │  Backend     │     │   IdP (사용자) (React/Next) (Spring/ (Keycloak│
│          │     │              │     │  Django)     │     │  Okta)└────┬─────┘     └──────┬───────┘     └──────┬───────┘     └────┬─────┘
1. 로그인 클릭   │                    │                  │
     │─────────────────▶│                    │                  │
     │                  │  2. /auth/login    │                  │
     │                  │───────────────────▶│                  │
     │                  │                    │  3. Redirect URL     │                  │                    │─────────────────▶│
4. IdP 로그인 페이지                  │                  │
     │◀──────────────────────────────────────────────────────────│
5. 사용자 인증 (ID/PW, MFA)           │                  │
     │──────────────────────────────────────────────────────────▶│
     │                  │                    │  6. Auth Code     │                  │                    │◀─────────────────│
     │                  │  7. CodeToken   │                  │
     │                  │◀───────────────────│                  │
     │                  │                      (id_token +     │                  │                    │   access_token +     │                  │                    │   refresh_token)8. Set-Cookie:  │                    │                  │
     │     access_token │                    │                  │
          (HttpOnly)   │                    │                  │
     │◀─────────────────│                    │                  │
9. 인증 완료,    │                    │                  │
     │     대시보드 이동  │                    │                  │
     │◀─────────────────│                    │                  │

인증된 요청 흐름 (Authenticated Request Flow)

┌──────────┐     ┌──────────────┐     ┌──────────────┐
Browser  │     │  Frontend    │     │  Backend└────┬─────┘     └──────┬───────┘     └──────┬───────┘
API 요청         │                    │
     │─────────────────▶│                    │
     │                  │  Cookie 자동 전송   │
  (access_token)     │                  │───────────────────▶│
     │                  │                    │  JWT 검증
     │                  │                      (서명, 만료, 클레임)
     │                  │   200 + 데이터     │
     │                  │◀───────────────────│
     │  렌더링           │                    │
     │◀─────────────────│                    │

토큰 갱신 흐름 (Token Refresh Flow)

┌──────────┐     ┌──────────────┐     ┌──────────────┐
Browser  │     │  Frontend    │     │  Backend└────┬─────┘     └──────┬───────┘     └──────┬───────┘
API 요청         │                    │
     │─────────────────▶│                    │
     │                  │  Cookie 전송        │
     │                  │───────────────────▶│
     │                  │   401 Unauthorized     │                  │◀───────────────────│
     │                  │                    │
     │                  │  POST /auth/refresh│
  (refresh_token    │
     │                  │   Cookie 전송)     │                  │───────────────────▶│
     │                  │   새 access_token  │
     │                  │   Set-Cookie     │                  │◀───────────────────│
     │                  │                    │
     │                  │  원래 요청 재시도    │
     │                  │───────────────────▶│
     │                  │   200 + 데이터     │
     │                  │◀───────────────────│
     │  렌더링           │                    │
     │◀─────────────────│                    │

로그아웃 흐름 (Logout Flow)

┌──────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────┐
Browser  │     │  Frontend    │     │  Backend     │     │   IdP└────┬─────┘     └──────┬───────┘     └──────┬───────┘     └────┬─────┘
     │  로그아웃 클릭     │                    │                  │
     │─────────────────▶│                    │                  │
     │                  │  POST /auth/logout │                  │
     │                  │───────────────────▶│                  │
     │                  │                    │  Revoke Token     │                  │                    │─────────────────▶│
     │                  │   Set-Cookie:      │                  │
     │                  │   access_token=""  │                  │
     │                  │   Max-Age=0        │                  │
     │                  │◀───────────────────│                  │
     │  쿠키 삭제,       │                    │                  │
     │  로그인 페이지     │                    │                  │
     │◀─────────────────│                    │                  │

핵심 포인트: 백엔드가 HttpOnly Cookie로 토큰을 관리하면 프론트엔드 JavaScript는 토큰에 직접 접근할 수 없습니다. 이것이 XSS 공격을 방어하는 가장 효과적인 전략입니다.


브라우저 저장소별 접근 가능성

토큰을 어디에 저장할지는 보안과 편의성의 트레이드오프입니다. 각 저장소의 특성을 정확히 이해해야 올바른 선택을 할 수 있습니다.

저장소JS 접근서버 자동 전송XSS 취약CSRF 취약
HttpOnly Cookie
Non-HttpOnly Cookie
localStorage
sessionStorage
Memory (JS 변수)

각 저장소 심층 분석:

  • HttpOnly Cookie: JavaScript에서 접근 불가능하므로 XSS에 안전합니다. 단, 브라우저가 모든 요청에 자동으로 쿠키를 첨부하므로 CSRF 공격에 취약합니다. SameSite 속성CSRF 토큰을 반드시 병행해야 합니다.
  • Non-HttpOnly Cookie: document.cookie로 접근 가능하므로 XSS와 CSRF 모두에 취약합니다. 가능하면 사용하지 마세요.
  • localStorage: 탭을 닫아도 데이터가 유지됩니다. 서버에 자동 전송되지 않아 CSRF에는 안전하지만, XSS 공격으로 토큰이 탈취될 수 있습니다.
  • sessionStorage: 탭 단위로 격리되고 탭을 닫으면 삭제됩니다. 보안 특성은 localStorage와 동일합니다.
  • Memory (JS 변수): 페이지 새로고침 시 소멸합니다. XSS에 완전히 안전하지는 않지만(실행 중인 스크립트가 접근 가능), 공격 난이도가 높습니다. Silent Refresh와 조합하면 좋은 전략입니다.

실전 권장: Access Token은 HttpOnly Cookie, CSRF 방어는 SameSite=Lax + CSRF Token 이중 적용. Refresh Token도 HttpOnly Cookie에 저장하되 Path를 /auth/refresh로 제한하세요.


쿠키 보안 속성 빠른 참조

쿠키는 단순한 key=value가 아닙니다. 보안 속성 하나를 빠뜨리면 인증 시스템 전체가 무너질 수 있습니다.

속성별 상세 설명

속성설명
HttpOnlytrueJavaScript에서 접근 차단. XSS 방어의 핵심
SecuretrueHTTPS 연결에서만 쿠키 전송
SameSiteStrict모든 크로스사이트 요청에서 쿠키 미전송. 가장 안전하지만 외부 링크 클릭 시 로그인 풀림
SameSiteLaxGET 네비게이션은 허용, POST 등은 차단. 대부분의 경우 권장
SameSiteNone크로스사이트 요청에서도 쿠키 전송. 반드시 Secure와 함께 사용. SSO에서 필수
Domain.example.com서브도메인 간 쿠키 공유. SSO에서 중요
Path/auth해당 경로 하위에서만 쿠키 전송
Max-Age3600초 단위 만료 시간. 0이면 즉시 삭제
Expires날짜 문자열절대 만료 시각. Max-Age가 우선

실전 설정 예시

Set-Cookie: access_token=eyJhbGciOi...;
  HttpOnly;
  Secure;
  SameSite=Lax;
  Path=/;
  Max-Age=900;
  Domain=.myservice.com

Set-Cookie: refresh_token=dGhpcyBpcyBh...;
  HttpOnly;
  Secure;
  SameSite=Strict;
  Path=/api/auth/refresh;
  Max-Age=604800;
  Domain=.myservice.com

Set-Cookie: csrf_token=abc123def456;
  Secure;
  SameSite=Lax;
  Path=/;
  Max-Age=900;
  Domain=.myservice.com

주의: csrf_tokenHttpOnly가 아닙니다. 프론트엔드가 이 값을 읽어서 요청 헤더(X-CSRF-Token)에 포함해야 하므로 JavaScript 접근이 필요합니다.

SameSite 전략 결정 트리:

SSO(크로스 도메인) 필요?
├── YesSameSite=None; Secure (+ CSRF Token 필수)
└── No
    ├── 외부 링크에서 유입 시 로그인 유지 필요?
    │   ├── YesSameSite=Lax
    │   └── NoSameSite=Strict
    └── API 전용 쿠키?
        └── SameSite=Strict (가장 안전)

JWT 구조와 핵심 클레임

JWT(JSON Web Token)는 .으로 구분된 세 부분으로 구성됩니다.

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.     Header (Base64URL)
eyJzdWIiOiJ1c2VyMTIzIiwicm9sZXMiOlsiQU...Payload (Base64URL)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQ...Signature
{
  "alg": "RS256", // 서명 알고리즘 (RS256, HS256, ES256 등)
  "typ": "JWT", // 토큰 타입
  "kid": "key-id-001" // Key ID (JWK Set에서 공개키 식별용)
}

Payload (Claims)

{
  "sub": "user123", // Subject — 사용자 고유 식별자
  "iss": "https://idp.myservice.com", // Issuer — 토큰 발급자
  "aud": "https://api.myservice.com", // Audience — 토큰 수신 대상
  "exp": 1741420800, // Expiration — 만료 시각 (Unix timestamp)
  "iat": 1741417200, // Issued At — 발급 시각
  "nbf": 1741417200, // Not Before — 이 시각 이전에는 무효
  "jti": "unique-token-id-789", // JWT ID — 토큰 고유 ID (재사용 방지)
  "roles": ["ADMIN", "USER"], // Custom — 사용자 권한
  "tenant_id": "tenant-abc", // Custom — 멀티테넌트 식별
  "email": "user@example.com" // Custom — 사용자 이메일
}

Signature 검증

RSASHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  publicKey
)

JWT 파싱 예시 (의사 코드)

import base64, json

def parse_jwt(token):
    header_b64, payload_b64, signature = token.split(".")

    # Base64URL 디코딩 (패딩 보정)
    header = json.loads(
        base64.urlsafe_b64decode(header_b64 + "==")
    )
    payload = json.loads(
        base64.urlsafe_b64decode(payload_b64 + "==")
    )

    # 만료 검증
    import time
    if payload["exp"] < time.time():
        raise Exception("토큰이 만료되었습니다")

    # 발급자 검증
    if payload["iss"] != "https://idp.myservice.com":
        raise Exception("신뢰할 수 없는 발급자입니다")

    return header, payload

주의: 실제 운영 환경에서는 반드시 서명을 검증해야 합니다. 위 코드는 구조 이해를 위한 예시이며, PyJWT, jose, jsonwebtoken 등 검증된 라이브러리를 사용하세요.

JWT vs 세션(Session) 비교:

항목JWT (Stateless)세션 (Stateful)
서버 저장소불필요필요 (Redis, DB)
수평 확장용이세션 스토어 공유 필요
즉시 무효화어려움 (Blocklist 필요)쉬움 (세션 삭제)
토큰 크기큼 (클레임 포함)작음 (세션 ID만)
적합 시나리오MSA, API Gateway모놀리식, 단일 서버

CORS와 Credential 전송

쿠키 기반 인증에서 가장 많은 개발자가 삽질하는 구간이 CORS(Cross-Origin Resource Sharing) 설정입니다. 프론트엔드와 백엔드의 도메인이 다를 때 쿠키 전송이 차단되는 문제는 거의 모든 프로젝트에서 한 번쯤 겪습니다.

올바른 설정

프론트엔드 (fetch API):

// credentials: 'include'가 핵심
const response = await fetch('https://api.myservice.com/users/me', {
  method: 'GET',
  credentials: 'include', // 쿠키를 포함하여 전송
  headers: {
    'Content-Type': 'application/json',
    'X-CSRF-Token': getCsrfToken(), // CSRF 토큰 헤더
  },
})

프론트엔드 (Axios):

const api = axios.create({
  baseURL: 'https://api.myservice.com',
  withCredentials: true, // 쿠키를 포함하여 전송
})

// 인터셉터로 CSRF 토큰 자동 첨부
api.interceptors.request.use((config) => {
  const csrfToken = getCookieValue('csrf_token')
  if (csrfToken) {
    config.headers['X-CSRF-Token'] = csrfToken
  }
  return config
})

백엔드 응답 헤더:

Access-Control-Allow-Origin: https://app.myservice.com   ← 정확한 Origin
Access-Control-Allow-Credentials: true                    ← 필수
Access-Control-Allow-Headers: Content-Type, X-CSRF-Token ← 커스텀 헤더 허용
Access-Control-Allow-Methods: GET, POST, PUT, DELETE      ← 허용 메서드
Access-Control-Expose-Headers: X-Request-Id               ← 프론트에서 읽을 헤더

흔한 실수와 해결법

실수 1: Access-Control-Allow-Origin: *credentials 동시 사용

# 이렇게 하면 브라우저가 차단합니다
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
# → 에러: credentials 모드에서는 와일드카드 Origin 불가

해결: Origin을 정확하게 지정하세요. 여러 Origin을 지원해야 한다면 요청의 Origin 헤더를 확인하고 화이트리스트에 있는 경우 동적으로 설정합니다.

# Django 예시
ALLOWED_ORIGINS = [
    'https://app.myservice.com',
    'https://admin.myservice.com',
]

# django-cors-headers 설정
CORS_ALLOWED_ORIGINS = ALLOWED_ORIGINS
CORS_ALLOW_CREDENTIALS = True

실수 2: Preflight 요청(OPTIONS)에서 쿠키 전송 기대

# Preflight(OPTIONS) 요청에는 쿠키가 포함되지 않습니다!
# OPTIONS 응답에서 인증을 요구하면 안 됩니다.
# → Backend의 인증 필터에서 OPTIONS 메서드를 제외하세요.

실수 3: SameSite=Strict 쿠키가 크로스오리진 요청에서 전송되지 않음

# 프론트: https://app.myservice.com
# 백엔드: https://api.myservice.com
# → 서로 다른 Origin이므로 SameSite=Strict 쿠키는 전송되지 않습니다
# → SameSite=None; Secure 또는 같은 상위 도메인 사용

실수 4: 로컬 개발 환경에서 localhost vs 127.0.0.1

# localhost:3000 → localhost:8080 : 같은 사이트 (쿠키 전송됨)
# localhost:3000127.0.0.1:8080 : 다른 사이트! (쿠키 전송 안됨)
# → 개발 환경에서도 동일한 호스트명을 사용하세요

시리즈 목차

이 시리즈는 총 5편으로 구성되어 있습니다. 이 인덱스 페이지에서 공통 개념을 익힌 후, 각 프레임워크별 실전 구현으로 이동하세요.

제목핵심 내용
0편현재 글 (인덱스)인증 흐름 전체 지도, 공통 개념 정리
1편Spring BootSecurityFilterChain, JWT 필터, CORS 설정, CSRF 방어
2편DjangoDRF + SimpleJWT, SessionMiddleware, django-cors-headers
3편ReactAxios 인터셉터, Silent Refresh, Protected Route
4편Next.jsMiddleware, Server Actions, SSR 쿠키 전달, next-auth
5편통합 실전편 — SSO/OIDC + 하이브리드 아키텍처Keycloak/Okta 연동, BFF 패턴, 멀티 서비스 SSO

읽는 순서 권장:

  1. 이 인덱스 글에서 전체 흐름을 파악합니다.
  2. 자신이 사용하는 백엔드 프레임워크 편(1편 또는 2편)을 읽습니다.
  3. 프론트엔드 편(3편 또는 4편)을 읽습니다.
  4. 5편에서 전체를 통합하는 아키텍처를 학습합니다.

보안 체크리스트 (시리즈 공통)

프레임워크에 관계없이 모든 인증 시스템에 적용해야 하는 보안 항목입니다. 배포 전 반드시 확인하세요.

쿠키 설정

  • Access Token 쿠키에 HttpOnly 속성이 설정되어 있는가?
  • 모든 인증 쿠키에 Secure 속성이 설정되어 있는가?
  • SameSite 속성이 서비스 아키텍처에 맞게 설정되어 있는가?
  • Refresh Token 쿠키의 Path가 갱신 엔드포인트로 제한되어 있는가?
  • 쿠키의 Max-Age가 적절한 시간으로 설정되어 있는가?
  • 쿠키의 Domain이 필요한 범위로만 제한되어 있는가?

토큰 관리

  • Access Token의 만료 시간이 충분히 짧은가? (권장: 5~15분)
  • Refresh Token의 만료 시간이 설정되어 있는가? (권장: 7~30일)
  • Refresh Token Rotation이 구현되어 있는가?
  • 탈취된 Refresh Token을 무효화할 수 있는 메커니즘이 있는가?
  • JWT 서명에 RS256 또는 ES256 비대칭 알고리즘을 사용하고 있는가?
  • JWT의 iss, aud, exp 클레임을 모두 검증하고 있는가?

CSRF 방어

  • 상태 변경 요청(POST, PUT, DELETE)에 CSRF 토큰을 검증하고 있는가?
  • CSRF 토큰이 요청마다 또는 세션마다 갱신되는가?
  • SameSite 쿠키 속성과 CSRF 토큰을 이중으로 적용했는가?

CORS 설정

  • Access-Control-Allow-Origin에 와일드카드(*)를 사용하지 않는가?
  • Access-Control-Allow-Credentials: true가 설정되어 있는가?
  • 허용할 Origin 목록이 화이트리스트로 관리되고 있는가?
  • Preflight 요청(OPTIONS)이 인증 없이 통과하도록 설정되어 있는가?

전송 보안

  • 모든 통신이 HTTPS를 통해 이루어지는가?
  • HSTS(HTTP Strict Transport Security) 헤더가 설정되어 있는가?
  • TLS 1.2 이상을 사용하고 있는가?

로그아웃

  • 로그아웃 시 서버 측 세션/토큰이 무효화되는가?
  • 로그아웃 시 모든 인증 쿠키가 삭제되는가?
  • SSO 환경에서 Single Logout(SLO)이 구현되어 있는가?

흔한 버그와 오해

오해 1: "JWT는 암호화되어 있다"

JWT는 서명(Signed)되어 있을 뿐 암호화(Encrypted)되어 있지 않습니다. Base64URL 인코딩은 암호화가 아닙니다. 누구나 Payload를 디코딩하여 내용을 읽을 수 있습니다.

# JWT Payload 디코딩 (누구나 가능)
echo "eyJzdWIiOiJ1c2VyMTIzIn0" | base64 -d
# 출력: {"sub":"user123"}

민감한 정보(비밀번호, 주민번호 등)를 JWT Payload에 절대 넣지 마세요. 정말 암호화가 필요하다면 JWE(JSON Web Encryption)를 사용하세요.

오해 2: "localStorage에 JWT를 저장해도 괜찮다"

SPA 프레임워크의 많은 튜토리얼이 localStorage에 JWT를 저장하는 예제를 보여줍니다. 이는 XSS 공격에 취약합니다. 서드파티 라이브러리 하나의 취약점만으로 토큰이 탈취될 수 있습니다.

// 위험한 패턴
localStorage.setItem('token', jwt)

// 안전한 패턴: HttpOnly Cookie 사용 (서버에서 설정)
// 프론트엔드는 토큰을 직접 다루지 않음

오해 3: "SameSite=Lax이면 CSRF 공격이 완전히 방어된다"

SameSite=Lax는 대부분의 CSRF를 방어하지만 완전하지 않습니다. 크로스사이트 GET 요청에는 쿠키가 전송됩니다. 만약 GET 요청으로 상태를 변경하는 API가 있다면 여전히 취약합니다.

# GET /api/users/delete?id=123  ← 이런 APISameSite=Lax로도 방어 불가!
# → 상태 변경은 반드시 POST/PUT/DELETE로 설계하세요

오해 4: "Refresh Token은 Access Token보다 안전하다"

Refresh Token은 장기간 유효하므로 탈취되면 Access Token보다 더 위험합니다. Refresh Token이 탈취되면 공격자가 무한정 새로운 Access Token을 발급받을 수 있습니다.

방어 전략:

  • Refresh Token Rotation: 갱신 시 이전 토큰 즉시 무효화
  • Token Family 추적: 이미 사용된 Refresh Token이 다시 사용되면 해당 Family 전체 무효화
  • Refresh Token을 HttpOnly Cookie에 저장하고 Path 제한

오해 5: "CORS가 서버를 보호해준다"

CORS는 브라우저의 정책입니다. curl, Postman, 서버 간 통신에서는 CORS가 적용되지 않습니다. CORS는 악성 웹사이트가 사용자의 브라우저를 이용해 API를 호출하는 것을 방지할 뿐, API 자체를 보호하지 않습니다.

# CORS와 무관하게 동작
curl -X POST https://api.myservice.com/data \
  -H "Cookie: access_token=stolen_token"
# → 서버 측 토큰 검증이 반드시 필요합니다

흔한 버그: 토큰 갱신 레이스 컨디션

여러 API 요청이 동시에 401을 받으면 Refresh 요청도 여러 번 발생합니다. Refresh Token Rotation을 사용하는 경우 첫 번째 요청만 성공하고 나머지는 실패합니다.

// 해결: 갱신 요청을 하나로 모으는 패턴
let refreshPromise = null

async function refreshToken() {
  if (refreshPromise) return refreshPromise // 이미 갱신 중이면 대기

  refreshPromise = axios.post('/auth/refresh').finally(() => {
    refreshPromise = null
  })

  return refreshPromise
}

참고자료

이 시리즈를 작성하면서 참고한 공식 문서와 표준 명세입니다. 인증 시스템을 설계할 때 반드시 원문을 확인하세요.

표준 명세 (RFC)

  1. RFC 7519 — JSON Web Token (JWT) — JWT 표준 명세. 클레임, 서명, 검증 절차 정의
  2. RFC 6749 — OAuth 2.0 Authorization Framework — OAuth 2.0 핵심 프레임워크. Grant Type별 흐름 정의
  3. RFC 6750 — OAuth 2.0 Bearer Token Usage — Bearer Token 전송 방법 (Authorization 헤더, 쿼리 파라미터 등)
  4. RFC 7517 — JSON Web Key (JWK) — 공개키 배포를 위한 JWK Set 표준
  5. RFC 6265 — HTTP State Management Mechanism (Cookie) — HTTP 쿠키 표준 명세

OpenID Connect

  1. OpenID Connect Core 1.0 — OAuth 2.0 위에 인증(Authentication) 레이어를 추가한 표준

보안 가이드라인

  1. OWASP — Session Management Cheat Sheet — 세션 관리 보안 모범 사례
  2. OWASP — JSON Web Token Cheat Sheet — JWT 사용 시 보안 체크리스트
  3. OWASP — Cross-Site Request Forgery Prevention — CSRF 방어 전략

프레임워크 공식 문서

  1. MDN — HTTP Cookies — 쿠키 속성(SameSite, HttpOnly, Secure 등) 상세 설명
  2. Spring Security — OAuth 2.0 Resource Server — Spring Boot JWT 인증 공식 가이드
  3. Django REST Framework — Authentication — DRF 인증 메커니즘 공식 문서
  4. Next.js — Authentication — Next.js App Router 기반 인증 구현 가이드
  5. MDN — CORS — Cross-Origin Resource Sharing 완전 가이드