Skip to content

feat: dev/staging 환경 미승인 사용자 404 처리 (세션 쿠키 기반 게이트) #334

Description

@iOdiO89

구현할 기능

dev(dev.piki.day)/staging(staging.piki.day) 웹에 어드민 세션이 없는 사용자가 접속하면 404 페이지를 보여준다.
승인된 사용자(디스코드 /piki-admin dev 링크로 세션 등록)만 접속 가능하게 하고, 실서비스(piki.day)는 영향 없음.

배경 / 조사 결과

  • 디스코드 봇 링크로 등록 페이지에 접속하면 백엔드가 세션 쿠키(JSESSIONID) 를 심어줌 (59분 세션)
    • "IP 세션"처럼 보이지만 실제 판별 기준은 쿠키 — 같은 기기여도 쿠키 없이(curl, 시크릿 창) 호출하면 404 확인됨
  • 백엔드에 세션 확인용 엔드포인트가 이미 있음: GET /admin/session/ttl
    • 세션 있음 → 200 {"remainingSeconds":3600} + 호출 시 세션 자동 연장
    • 세션 없음 → 404 (빈 바디)
    • 세션 있음/없음 판단을 이 엔드포인트 하나로 해결 가능. 신규 API 불필요
  • Vercel 무료 플랜이라 Password Protection / Trusted IPs 등 플랫폼 기능은 사용 불가 → 앱 레벨(proxy.ts)에서 처리
  • 환경 구분은 NEXT_PUBLIC_STAGE=dev|staging|production env로 이미 가능

동작 흐름

dev.piki.day 접속
    ↓
proxy.ts: NEXT_PUBLIC_STAGE === 'production'? → 게이트 skip (기존 흐름 그대로)
    ↓ dev/staging이면
통과 쿠키(짧은 TTL, 서명됨) 있으면 → 통과 (백엔드 호출 생략)
    ↓ 없으면
접속자의 쿠키를 그대로 실어 GET {API_URL}/admin/session/ttl 호출
    ↓
200 → 통과 쿠키 심고 통과
404 → not-found 페이지로 rewrite (404 상태코드)
  • 통과 쿠키(약 5분)로 매 요청마다 백엔드를 호출하지 않도록 캐싱 — 세션 만료자도 최대 5분 내 차단됨
  • ttl 엔드포인트가 호출마다 세션을 연장하므로, 사이트를 쓰는 동안은 세션이 안 끊김 (개발 UX상 장점)

🙏 백엔드 선행 작업 (1건)

현재 JSESSIONID 쿠키의 Domain이 dev.api.piki.day(host-only)라서 웹(dev.piki.day) 요청에는 쿠키가 실리지 않음.
쿠키가 웹까지 딸려 오도록 아래 중 하나 필요:

  1. 세션 쿠키 Domain을 .piki.day로 확장 — Spring 기준 설정 한 줄
    server.servlet.session.cookie.domain: .piki.day
  2. (1이 께름칙하면) 등록 시점에 게이트 전용 쿠키를 Domain=.piki.day로 하나 더 발급

※ 웹 미들웨어는 서버에서 요청 헤더를 읽으므로 HttpOnly 쿠키 그대로 사용 가능 (변경 불필요)

작업 상세 내용

  • (백엔드) 세션 쿠키 Domain .piki.day로 확장 (위 참고)
  • proxy.ts 최상단에 환경 게이트 추가 (NEXT_PUBLIC_STAGE !== 'production'일 때만 동작)
  • 세션 확인 결과 캐싱용 통과 쿠키 (서명, TTL 약 5분)
  • 미승인 사용자 → not-found 페이지 rewrite (404 상태코드)
  • dev/staging 응답에 X-Robots-Tag: noindex 헤더 추가 (검색 노출 방지)
  • 검증: 시크릿 창 404 / 등록 후 정상 접속 / production 영향 없음

참고 / 추후 고민

  • 앱(WebView)으로 dev 접속 시: 웹뷰 쿠키 저장소에 세션 쿠키가 있어야 함 → 등록 링크를 앱 안에서 열어야 함. 404 페이지에 등록 안내를 넣는 방안 등 게이트 적용 후 별도 논의

Metadata

Metadata

Assignees

Labels

WEBfeatureNew feature or request

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions