Skip to content

Google 로그인 화면 약관 분리 + SIGNUP_REQUIRED 시 약관 페이지로 리다이렉트 #90

@parkjuyeong0312

Description

@parkjuyeong0312

설명

백엔드 refactor/login-agreement 브랜치에서 Google 로그인 응답에 SIGNUP_REQUIRED 분기와 임시 signupToken, 가입 완료 엔드포인트 POST /auth/google/signup이 추가됐다.
프론트는 이를 사용해 약관 동의 시점을 로그인 전 → 신규 가입자 한정으로 로그인 후로 옮긴다.

요구사항 (UX)

  • 로그인 화면: 약관 UI 없음. Google 로그인 버튼만 노출.
  • 콜백 처리: Google 인증 후 백엔드 응답에 따라 분기
    • 기존 회원, 약관 최신 → 즉시 로그인 완료
    • 신규 가입자 → 약관 동의 페이지로 리다이렉트
    • 기존 회원, 약관 갱신 필요 → 약관 재동의 안내 → 동의 후 다시 로그인 시도
  • 약관 동의 페이지(신규 가입): 약관 표시 + 전체 동의 → 가입 완료 → 로그인 상태로 전환

백엔드 API 스펙 (이번 브랜치 기준)

POST /auth/google/login

요청: { "code": "..." } (약관 동의 여부는 더 이상 필수로 함께 보낼 필요 없음, 보내려면 agreementsAccepted: true)

응답 분기:

케이스 상태 body 쿠키
기존 회원 + 약관 최신 200 없음 access/refresh 발급
기존 회원 + 약관 변경됨 + agreementsAccepted=true 200 없음 access/refresh 발급
기존 회원 + 약관 변경됨, 동의 없음 401 AGREEMENTS_REACCEPTANCE_REQUIRED 에러 없음
신규 + 동의 없음 200 { "status":"SIGNUP_REQUIRED", "signupToken":"...", "expiresInSeconds":600 } 없음
신규 + agreementsAccepted=true 200 없음 access/refresh 발급 (즉시 가입)

POST /auth/google/signup (신규)

요청: { "signupToken": "...", "agreementsAccepted": true }

  • 200 → 쿠키 발급, body 없음 (가입 완료)
  • 400 AGREEMENTS_NOT_ACCEPTED → 동의 누락/false
  • 401 GOOGLE_SIGNUP_TOKEN_NOT_FOUND → 토큰 없음/만료/재발급으로 무효화/형식 오류

GET /api/agreements/current (변경 없음 / 이미 사용 중)

약관 동의 페이지에서 사용. 인증 불필요. contentFormat=MARKDOWN.

POST /api/users/me/agreements (변경 없음 / 이미 사용 중)

로그인된 상태의 재동의용. 이번 흐름에선 사용 안 함.

알아둘 점

  • signupTokenopaque UUID, TTL 10분. 값에서 의미를 추론하지 말 것, 영구 저장 금지(메모리/sessionStorage 권장).
  • 같은 Google 계정으로 로그인을 다시 시도하면 이전 signupToken은 즉시 무효화됨 (마지막 시도만 유효). 약관 화면을 띄워둔 채 다른 탭/창에서 재로그인하면 가입 완료가 실패할 수 있음 — 그 경우 GOOGLE_SIGNUP_TOKEN_NOT_FOUND(401)로 떨어지므로 재로그인 안내가 필요.
  • expiresInSeconds(600초) 만료 후에도 동일하게 GOOGLE_SIGNUP_TOKEN_NOT_FOUND로 처리됨.
  • 신규 가입자가 첫 로그인 요청에 agreementsAccepted=true를 같이 보내면 백엔드는 SIGNUP_REQUIRED를 거치지 않고 즉시 가입한다. 이번 UX 의도(약관을 로그인 후로 옮기기)대로 가려면 신규 흐름에선 agreementsAccepted보내지 않는다.
  • 기존 회원 재동의 흐름: AGREEMENTS_REACCEPTANCE_REQUIRED(401)가 떨어졌을 때, 프론트는 약관 화면 → 동의 → 다시 Google 로그인 시작(이번엔 agreementsAccepted=true 포함)으로 처리. (로그인 안 된 상태라 POST /api/users/me/agreements는 사용 불가)
  • signupToken/응답 분기 처리는 BFF route handler가 백엔드 응답(상태코드 + body)을 그대로 흘려보낼 수 있어야 함 — 현재 POST /api/auth/google route는 body 패스스루 + Set-Cookie 전달이라 큰 변경은 없지만, 200 + JSON body 케이스가 새로 생긴다는 점만 유의.
  • POST /auth/google/signup도 동일하게 쿠키 패스스루 BFF route가 필요함.

브랜치 정책

  • 이 변경은 백엔드 refactor/login-agreement 브랜치 전용. main, dev 어디에도 머지되어 있지 않다.
  • 백엔드는 양측 합의 전까지 main/dev에 머지하지 않는다. 프론트 작업 완료 + 함께 확인된 시점에만 통합 반영.
  • 프론트 작업도 별도 브랜치에서 진행하고, 백엔드 통합 시점이 확정될 때까지 프론트 dev/main에 머지하지 말 것.

실행 경로 (백엔드 띄우기)

cd <백엔드 레포 경로>
git fetch origin
git checkout refactor/login-agreement
git pull origin refactor/login-agreement

docker compose --env-file .env.dev \
  -f compose.db.dev.yaml -f compose.app.dev.yaml up -d --build

docker compose --env-file .env.dev \
  -f compose.db.dev.yaml -f compose.app.dev.yaml down
  • 앱: http://localhost:8080
  • Swagger: http://localhost:8080/swagger-ui/index.html
  • PostgreSQL 5433, MongoDB 27017, Redis 기본 포트

main은 약관 엔드포인트 자체가 없고, dev는 약관은 있지만 SIGNUP_REQUIRED 흐름이 없다. 반드시 refactor/login-agreement 브랜치를 띄울 것.

참고

  • 백엔드 설계: docs/superpowers/specs/2026-06-08-google-signup-token-design.md, docs/superpowers/specs/2026-06-08-backend-agreements-design.md
  • 에러 코드: AGREEMENTS_NOT_ACCEPTED, AGREEMENTS_REACCEPTANCE_REQUIRED, GOOGLE_SIGNUP_TOKEN_NOT_FOUND, AGREEMENT_CONFIGURATION_INVALID

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions