bibimbap/docs/user-signup-schema.md

5.4 KiB

회원가입 정보 구조

이 문서는 usersuser_auth_identities 테이블 구조를 기준으로, 회원가입 시 필요한 정보와 저장 방식을 정리한다.

기본 개념

users는 서비스 내부의 사용자 계정이다.

user_auth_identities는 사용자가 어떤 방식으로 로그인했는지를 저장한다. 예를 들어 게스트 로그인, 구글 로그인, 카카오 로그인은 모두 이 테이블에 저장된다.

하나의 users 계정에는 여러 로그인 방식이 연결될 수 있다.

예시:

users.id = 1
- guest
- google
- kakao

단, 현재 구조에서는 같은 로그인 제공자는 하나만 연결할 수 있다.

예를 들어 하나의 사용자 계정에 구글 계정 2개를 동시에 연결할 수는 없다.

회원가입 공통 입력값

회원가입 요청은 로그인 제공자와 무관하게 아래 정보를 기준으로 처리한다.

필드 필수 설명
provider 필수 로그인 제공자. guest, google, email, kakao, naver, github, apple 중 하나
providerUserId 필수 로그인 제공자가 내려준 사용자 고유 ID
displayName 필수 서비스에서 표시할 사용자 이름
email 선택 로그인 제공자에서 받은 이메일
avatarUrl 선택 로그인 제공자에서 받은 프로필 이미지 URL

게스트 회원가입

게스트 회원가입은 외부 제공자가 없기 때문에 서버가 providerUserId를 생성한다.

추천 입력값:

{
  "provider": "guest",
  "displayName": "익명"
}

서버 처리:

저장 위치
users.display_name 요청의 displayName, 없으면 익명
users.canonical_email null
users.avatar_url null
users.role USER
users.status ACTIVE
user_auth_identities.provider guest
user_auth_identities.provider_user_id 서버가 생성한 게스트 ID
user_auth_identities.email null
user_auth_identities.display_name 요청의 displayName, 없으면 익명
user_auth_identities.avatar_url null

게스트 ID는 UUID 같은 충돌 가능성이 낮은 값으로 생성하는 것을 권장한다.

예시:

guest:550e8400-e29b-41d4-a716-446655440000

소셜 회원가입

소셜 회원가입은 클라이언트가 소셜 로그인 완료 후 받은 사용자 정보를 서버에 전달하거나, 서버가 토큰을 검증한 뒤 사용자 정보를 조회해서 저장한다.

추천 입력값:

{
  "provider": "google",
  "providerUserId": "109876543210123456789",
  "displayName": "홍길동",
  "email": "user@example.com",
  "avatarUrl": "https://example.com/avatar.png"
}

서버 처리:

저장 위치
users.display_name 요청의 displayName
users.canonical_email 요청의 email
users.avatar_url 요청의 avatarUrl
users.role USER
users.status ACTIVE
user_auth_identities.provider 요청의 provider
user_auth_identities.provider_user_id 요청의 providerUserId
user_auth_identities.email 요청의 email
user_auth_identities.display_name 요청의 displayName
user_auth_identities.avatar_url 요청의 avatarUrl

이메일 기준 처리

users.canonical_email은 대표 이메일이다.

소셜 로그인 제공자가 이메일을 내려주면 canonical_email에 저장할 수 있다.

주의할 점:

  • 이메일이 없는 제공자도 있을 수 있다.
  • 이메일 인증 여부가 불명확한 경우 곧바로 계정 병합 기준으로 쓰면 위험할 수 있다.
  • 같은 이메일로 이미 가입된 사용자가 있더라도 자동 병합은 신중하게 처리해야 한다.

중복 가입 판단

회원가입 또는 로그인 시 먼저 user_auth_identities에서 아래 조건으로 기존 연결 정보를 찾는다.

select *
from user_auth_identities
where provider = :provider
  and provider_user_id = :providerUserId;

결과가 있으면 신규 회원가입이 아니라 기존 사용자 로그인으로 처리한다.

결과가 없으면 신규 users를 생성하고, 이어서 user_auth_identities를 생성한다.

계정 연결

이미 로그인한 사용자가 추가 소셜 계정을 연결하는 경우에는 새 users를 만들지 않는다.

대신 현재 로그인한 users.iduser_auth_identities만 추가한다.

예시:

현재 로그인 사용자: users.id = 1
추가 연결 요청: google

처리 결과:
user_auth_identities.user_id = 1
user_auth_identities.provider = 'google'

현재 구조에서는 같은 사용자에게 같은 provider를 중복 연결할 수 없다.

추천 API 형태

게스트 회원가입

POST /api/auth/guest
Content-Type: application/json
{
  "displayName": "익명"
}

소셜 회원가입 또는 로그인

POST /api/auth/social
Content-Type: application/json
{
  "provider": "google",
  "providerUserId": "109876543210123456789",
  "displayName": "홍길동",
  "email": "user@example.com",
  "avatarUrl": "https://example.com/avatar.png"
}

실제 구현에서는 클라이언트가 넘긴 providerUserId를 그대로 신뢰하기보다, 가능하면 서버에서 소셜 로그인 토큰을 검증한 뒤 provider 사용자 ID를 확정하는 방식을 권장한다.