Auth / 세션 / TURN·ICE 발급 — 코드레벨 동작 흐름 P2코드레벨

마지막 업데이트 2026-07-29

Auth / 세션 / TURN·ICE 발급 — 코드레벨 동작 흐름 P2 코…: 입력: 개요 · 범위, 주요 처리 단계: 토큰 갱신 lib/auth-refresh.ts, 결과: 파일 · 라인 레퍼런스 흐름
동작 흐름 요약
  1. 입력: 개요 · 범위
  2. 주요 처리 단계: 토큰 갱신 lib/auth-refresh.ts
  3. 결과: 파일 · 라인 레퍼런스
작성일: 2026-06-14 대상: 개발자 — 인증·세션·WebRTC 자격증명 파악 핵심 파일: lib/session.ts, lib/auth-refresh.ts, api/{members,users}/auth, api/ice-servers
💬 대화로 먼저 이해하기 — "출입증·경비실 비유" (비개발자·처음 읽는 사람용)
Q치료사나 아동이 PIN으로 로그인하면 무슨 일이 일어나요?
A건물 경비실(Next.js BFF)이 본사(ppi-api)에 신원을 확인하고 출입증(토큰)을 발급받아요. 그런데 출입증을 본인 손에 쥐여 주지 않고 경비실의 잠긴 사물함(암호화 httpOnly 쿠키)에 보관해요. 치료사(member)와 아동(child)은 사물함도 따로 씁니다.
Q출입증 유효기간이 수업 중에 끝나면 쫓겨나나요?
A그걸 막으려고 만료 30분 전부터 미리 재발급해요(만료 버퍼). 수업이 20분이니, 수업 시작 때 멀쩡했던 출입증이 수업 도중 만료되는 일이 없도록 버퍼를 수업 길이보다 크게 잡은 거예요.
Q재발급이 실패하면 바로 로그아웃되나요?
A아니요. 본사가 "이 출입증은 무효"(401)라고 확실히 답할 때만 회수해요. 발급 창구가 잠깐 고장 나거나(5xx) 전화가 안 되는(네트워크) 건 일시 장애(transient)로 보고 기존 출입증을 유지합니다 — 잠깐의 장애로 수업 중 강제 로그아웃되는 사고를 막는 규칙이에요.
QTURN/ICE 발급은 뭐예요?
A영상통화의 직통 연결이 방화벽에 막힐 때 쓰는 중계소(TURN) 이용권이에요. Metered라는 중계 업체의 이용권을 서버가 대신 받아 전달하고, 발급 열쇠(apiKey)는 서버만 갖고 있어요. 세부 규칙은 하단 "함정 · 주의"와 lib/auth-refresh.ts를 보세요.

개요 · 범위

치료사(member)·아동(child) PIN 로그인과 세션(쿠키) 관리, 토큰 갱신, 그리고 WebRTC용 TURN/ICE 자격증명 발급. Next.js가 BFF로서 외부 ppi-api 인증을 중계하고 토큰을 암호화 쿠키(iron-session)에 보관한다.

PIN 로그인 api/members/auth, api/users/auth

POST /api/members/auth { name, pin }   // 치료사
POST /api/users/auth   { name, pin }   // 아동
  → ppiApiClient.login(name, pin)      // 외부 ppi-api
  → session.{accessToken, refreshToken, accessTokenExpiresAt, *Id, *Name, role}
  → session.save()  (암호화 쿠키)

세션 (iron-session) lib/session.ts

memberchild
쿠키ppi-member-sessionppi-child-session
보관accessToken/refreshToken/accessTokenExpiresAt + 식별 정보
옵션httpOnly, secure(prod), sameSite lax, maxAge 14일, SESSION_SECRET 암호화
만료 버퍼 30분: isAccessTokenExpired는 만료 30분 전부터 만료로 본다. 수업(20분) 동안 BFF 호출이 없어 토큰이 만료되는 일을 막기 위한 선제 갱신 버퍼.

토큰 갱신 lib/auth-refresh.ts

refresh 결과를 3가지로 분류해 "세션 폐기 vs 유지"를 정확히 판단한다(잘못 폐기하면 수업 중 로그아웃).

RefreshOutcome의미 / 처리
refreshed새 accessToken + expiresAt
invalid (401만)refresh token 무효 → 세션 폐기 OK
transient (400/5xx/네트워크)일시 장애 → 세션 유지(폐기 근거 아님), warn 로깅
핵심 컨벤션: ppi-api는 401만 refresh token 무효 신호. 400(BFF 요청 버그)/5xx(ppi-api 장애)로 세션을 폐기하면 안 된다 — 일시 장애에 사용자가 로그아웃되는 회귀 방지.

TURN/ICE 발급 api/ice-servers/route.ts

GET /api/ice-servers
  → getMeteredApiKey()  (SSM/시크릿)
  → GET ppi.metered.live/api/v1/turn/credentials?apiKey=...
  → { iceServers: [{ urls, username, credential }] }

함정 · 주의

파일 · 라인 레퍼런스

파일역할
api/members/auth/route.ts, api/users/auth/route.tsPIN 로그인 BFF
lib/session.tsiron-session member/child 쿠키·만료 버퍼
lib/auth-refresh.tsrefresh 결과 분류(refreshed/invalid/transient)
api/ice-servers/route.tsMetered TURN 자격증명
lib/ppi-api-client.ts외부 ppi-api 클라이언트

관련 문서