"로그인 됐다" 가 쿠키에 뭐가 들었느냐에 따라 와일드하게 다른 의미가 돼. 세 패턴이 지배적이고 각각 다른 실패 모드 가져.
| 패턴 | 쿠키 안 내용 | 서버 저장 | Revocation |
|---|---|---|---|
| Session 쿠키 | 랜덤 opaque 토큰 (예: 32 hex 문자) | DB 에 token → user_id, expires_at, ip 매핑 | row 삭제 — 즉시 |
| JWT (signed, stateless) | self-describing JSON + signature | 없음 | 만료까지 진짜 revoke 못 함; denylist 필요 |
| Bearer 토큰 (API key) | Authorization 헤더의 랜덤 문자열 | DB row + scope | row 삭제 |
솔로 앱한테 session 이 이기는 이유
이 퀘스트의 PIN layer 는 SQLite 테이블의 session 쿠키 써. 이유:
- 즉시 revocation. "Revoke All" 이 SQL
DELETE한 줄. JWT 는 stateless 의 핵심을 망가뜨리는 denylist 필요. - IP 에 묶여. 각 session row 가 발급된 IP 저장; mismatched IP = invalid. 공짜 anti-replay.
- admin 에서 보임. active session 리스트, 발급 시간, 발급 위치, 만료 시간 다 봐.
- 작아. 외부 의존성 없음; SQLite 는 Python 에 내장.
중요한 쿠키 플래그
| 플래그 | 효과 | 기본 입장 |
|---|---|---|
HttpOnly | JavaScript 가 쿠키 못 읽음 | 항상 ON — XSS 절도 차단 |
Secure | HTTPS 로만 전송 | 프로덕션 ON; localhost 만 OFF |
SameSite=Strict | cross-site 요청에 안 보냄 | 솔로 앱은 ON — cross-site flow 필요 없음 |
Max-Age | 수명 (초) | 제한 — 예: 30일, 절대 "infinite" 아님 |