개인정보 동의항목 전화번호 정보 수집 안됨

문의 시, 디벨로퍼스 앱ID를 알려주세요.

  • 비즈니스 정보 심사는 운영하시는 서비스와 디벨로퍼스앱이 일치하는지, 운영정책을 준수하는 신뢰할 수 있는 서비스인지 확인하는 절차입니다.
  • 개인정보 항목 심사는 운영하시는 서비스 일반회원가입에서 입력 받는 항목을 기준으로 제공됩니다.

앱 권한 신청이 반려되었습니다. FAQ

sw*****@nate.com

동의항목에 카카오계정 (전화번호) 필수동의 상태인데 유저 로그인시 전화번호 정보 수집이 안됩니다. 

안녕하세요.

확인을 위해 앱 ID 부탁드립니다.


앱ID
https://developers.kakao.com/console/app 에 표시되는 ID 값 입니다.
숫자로된 ID 입니다
ex) 123456

1410344 입니다

로그상 전화번호가 잘 전달되었습니다.

전달 안되었다는 유저의 앱유저ID 기재 해주시겠어요?

4b4fe46d-e97b-468d-b25d-dde2315c728d 입니다

기재하신 값은 앱유저ID가 아닙니다.

v2/user/me에서 전달하는 숫자로된 id 기재해주시면되고 함께 전달된 전화번호가 있는지 체크 해주시면됩니다.

4806995728 입니다

“phone_number”:“+82 10-35**-89**” 전화번호 전달된 것으로 확인됩니다.

현재 수파베이스 이용중인데 다른 정보는 정상적으로 수집되는데 전화번호만 null로 나옵니다

정상 전달되었으니 개발하신 시스템 매핑 로직 살펴보시면 좋을 것 같습니다.

1. 카카오 프로필 셋업 — 핵심 매핑 (kakao-profile-setup.mts)

가장 복잡한 매핑 로직으로, 카카오 OAuth 로그인 후 사용자 프로필 데이터를 추출·정규화·저장합니다.

1-1. 데이터 소스 탐색 순서 (전화번호)

전화번호는 아래 우선순위로 여러 경로를 탐색합니다:

1순위: client_kakao_phone (클라이언트가 직접 카카오 API 호출하여 전달한 값)
2순위: kakaoApi.phone_number (서버에서 provider_token으로 카카오 /v2/user/me 호출)
3순위: kakaoApi.mobile / kakaoApi.mobile_number
4순위: identityData.kakao_account.phone_number (Supabase identities 배열)
5순위: identityData.phone_number / identityData.phone
6순위: meta.phone_number / meta.phone / meta.mobile
7순위: meta.kakao_account.phone_number
8순위: meta.provider_metadata.phone_number
9순위: meta.raw_user_meta_data.phone_number / phone / mobile
10순위: meta.custom_claims.phone_number
11순위: meta.user_metadata.phone_number
12순위: meta.identity_data.phone_number
13순위: deep_scan (재귀적으로 +82 또는 01X 패턴 탐색)

1-2. 전화번호 정규화 (normalizeKoreanPhone)

카카오에서 반환하는 전화번호 형식을 통일합니다:

입력                     → 출력
"+82 10-1234-5678"      → "01012345678"
"+82-10-1234-5678"      → "01012345678"
"+8210-1234-5678"       → "01012345678"
"+82 010-1234-5678"     → "01012345678"
"010-1234-5678"         → "01012345678"
"01012345678"           → "01012345678"

처리 파이프라인:

  1. 공백·하이픈·점·괄호 제거

  2. +82(0?)0 변환

  3. 남은 비숫자 문자 제거

  4. 01[016789]\d{7,8} 패턴 검증

1-3. 이름 추출 우선순위

1순위: client_kakao_name (클라이언트 전달)
2순위: kakaoApi.kakao_account.name (카카오 API 실명)
3순위: kakaoApi.kakao_account.profile.nickname
4순위: kakaoApi.properties.nickname
5순위: identityData.kakao_account.name
6순위: identityData.name / identityData.full_name
7순위: meta.full_name / meta.name / meta.nickname / meta.preferred_username

1-4. 카카오 API 호출 폴백 체계

[1차] OIDC 모드: Supabase GoTrue가 id_token(JWT)에서 클레임 자동 파싱
      → user_metadata/identity_data에 phone_number, name 등 포함

[2차] provider_token 폴백: OIDC에서 phone 못 얻은 경우
      → POST https://kapi.kakao.com/v2/user/me
      → Authorization: Bearer {provider_token}

[3차] Admin Key 폴백: provider_token 없는 경우
      → POST https://kapi.kakao.com/v2/user/me
      → Authorization: KakaoAK {KAKAO_ADMIN_KEY}
      → Body: target_id_type=user_id&target_id={kakaoUserId}

[4차] kakaoAccount 직접 참조: Admin Key도 없는 경우
      → kakaoAccount.phone_number 값이 있으면 직접 사용

1-5. kakaoAccount 소스 탐색 경로

kakaoAccount =
  kakaoIdentityData.kakao_account         // identities[].identity_data.kakao_account
  || meta.kakao_account                   // user_metadata.kakao_account
  || meta.raw_user_meta_data?.kakao_account
  || meta.provider_metadata?.kakao_account
  || meta.user_metadata?.kakao_account
  || kakaoIdentity?.identity_data?.kakao_account
  || meta.raw_user_meta_data?.provider_metadata?.kakao_account

1-6. 권한/동의 상태 진단

카카오 동의항목 상태를 다음 필드로 점검합니다:

필드 설명
has_phone_number 카카오 계정에 전화번호 등록 여부
phone_number_needs_agreement 전화번호 수집 동의 필요 여부
is_phone_number_verified 전화번호 인증 여부
has_email 이메일 등록 여부
email_needs_agreement 이메일 수집 동의 필요 여부
profile_nickname_needs_agreement 닉네임 수집 동의 필요 여부

권한 문제 감지 조건:

  • phone_number_needs_agreement=true 인데 값 없음 → 사용자 미동의 또는 비즈앱 설정 필요

  • has_phone_number=false → 카카오 계정에 전화번호 미등록

  • kakao_account 자체가 비어있음 → Supabase가 카카오 응답을 user_metadata에 미포함

  • phone_number 관련 필드가 전혀 없음 → 카카오 개발자 콘솔에서 “전화번호” 동의항목 미활성화

1-7. 프로필 저장 매핑

카카오 데이터          → Supabase profiles 테이블
─────────────────────────────────────────────────
phone (정규화됨)      → profiles.phone
kakao_id (provider_id/sub) → profiles.kakao_id
avatar_url/picture    → profiles.avatar_url
name/nickname         → profiles.full_name
email                 → profiles.email

카카오 데이터          → Supabase auth.users
─────────────────────────────────────────────────
phone (E.164 변환)    → auth.users.phone  (+821012345678 형식)
phone_confirm: true   → auth.users.phone_confirmed_at

1-8. 요청 OAuth 스코프

openid, profile_nickname, account_email, phone_number, name


2. 카카오 알림톡 매핑 (send-kakao-alimtalk.mts)

Solapi를 통해 카카오 알림톡을 발송하며, 실패 시 SMS 대체 발송합니다.

매핑 흐름

입력: { phone?, username?, message, templateId?, variables? }

[전화번호 확보]
  phone 직접 전달 → 사용
  또는 username → Supabase profiles.phone 조회

[전화번호 정규화]
  phone.replace(/[^0-9]/g, '') → 숫자만 추출

[알림톡 발송] (PFID + 템플릿 설정 시)
  to: 정규화된 전화번호
  from: SOLAPI_FROM_NUMBER
  text: message (SMS 대체 텍스트)
  kakaoOptions:
    pfId: SOLAPI_KAKAO_PFID
    templateId: 전달값 또는 SOLAPI_KAKAO_PROPOSAL_TEMPLATE_ID
    variables: 전달된 템플릿 변수 맵

[SMS 대체 발송] (알림톡 실패 또는 미설정 시)
  to/from/text만 사용


3. 비즈니스 제안 알림톡 템플릿 변수 매핑 (api-proposals.mts)

variables: {
  '#{이름}': influencerDisplayName,    // 인플루언서 표시명
  '#{업체명}': proposal.company_name,   // 제안 업체명
  '#{제안내용}': proposalSummary,       // 제안 요약 (200자 제한)
}


4. 카카오 친구톡/SMS 발송 (send-kakao-friendtalk.mts)

실제로는 Solapi SMS로 발송합니다 (카카오 친구톡 대신).

입력: { phone?, username?, message }
전화번호: phone 직접 또는 username → DB 조회
정규화: phone.replace(/[^0-9]/g, '')
발송: Solapi SMS (to, from, text)


5. 카카오 캐시 갱신 (api-kakao-cache-refresh.mts)

카카오톡 공유 시 OG 메타 캐시를 갱신합니다.

입력: { url: targetUrl }

API 호출:
  POST https://kapi.kakao.com/v2/util/scrape/flush
  Authorization: KakaoAK {KAKAO_REST_API_KEY}
  Content-Type: application/x-www-form-urlencoded
  Body: scrape_url={targetUrl}


6. 프론트엔드 카카오 사용자 매핑 (LiveStream.tsx)

interface KakaoUser {
  nickname: string;
  profileImage?: string;
}

// OAuth 로그인 스코프
scopes: 'openid profile_nickname account_email phone_number name'

// 로컬 저장
localStorage.setItem('picks_kakao_user', JSON.stringify(kakaoUser))

// 라이브 카트 연동
viewerNickname → cart.viewerNickname
viewerProfileImage → cart.viewerProfileImage


7. 환경변수 매핑

환경변수 용도
VITE_KAKAO_APP_KEY 프론트엔드 카카오 SDK 앱키
KAKAO_ADMIN_KEY 서버 Admin API 호출 (provider_token 폴백)
KAKAO_REST_API_KEY 카카오 캐시 갱신 API
SOLAPI_API_KEY / SOLAPI_API_SECRET Solapi 인증
SOLAPI_FROM_NUMBER SMS 발신번호
SOLAPI_KAKAO_PFID 카카오 비즈 채널 ID (알림톡 발송)
SOLAPI_KAKAO_PROPOSAL_TEMPLATE_ID 제안 알림톡 기본 템플릿 ID

현재 매핑인데 오류 있을까요

카카오 v2/user/me API 호출 응답 Response 가 어떻게 전달되었는지 로깅하셔서 가공전 데이터 먼저 확인 해보시겠어요?

안녕하세요, 답변 감사합니다.

말씀하신 대로 v2/user/me API 응답의 가공 전 데이터를 확인해 봤습니다. 현재 저희 서버 로그에서 확인되는 가공 전 원본 데이터 구조는 다음과 같습니다:

1. Supabase를 통한 OIDC 경로 (주요 경로)

저희는 Supabase GoTrue를 통해 카카오 OAuth를 처리하고 있습니다. 대부분의 경우 **v2/user/me**를 직접 호출하지 않고, Supabase가 카카오 id_token(JWT)을 파싱하여 전달한 데이터를 사용합니다.

이 경우 Supabase에서 전달받는 가공 전 데이터는:

// user_metadata (Supabase가 id_token에서 파싱한 데이터)
{
  "iss": "https://kauth.kakao.com",
  "sub": "카카오_사용자_ID",
  "nickname": "닉네임",
  "picture": "프로필이미지_URL",
  "email": "이메일"
  // ← phone_number 필드가 여기에 포함되지 않는 경우가 많음
}

// identities[].identity_data (카카오 provider)
{
  "sub": "카카오_사용자_ID",
  "nickname": "닉네임",
  "picture": "프로필이미지_URL",
  "email": "이메일"
  // ← kakao_account 객체 자체가 없거나, 있어도 phone_number가 없음
}

문제점: OIDC id_token 클레임에 **phone_number**가 포함되지 않아, Supabase **user_metadata**와 **identity_data**에 전화번호가 전달되지 않습니다.

2. v2/user/me 직접 호출 경로 (폴백)

OIDC에서 전화번호를 못 얻은 경우, **provider_token**으로 **v2/user/me**를 직접 호출합니다. 이때 받는 가공 전 원본 응답:

// POST https://kapi.kakao.com/v2/user/me
// Authorization: Bearer {provider_token}
{
  "id": 카카오_사용자_ID,
  "connected_at": "2024-XX-XXTXX:XX:XXZ",
  "properties": {
    "nickname": "닉네임",
    "profile_image": "이미지URL",
    "thumbnail_image": "이미지URL"
  },
  "kakao_account": {
    "profile_nickname_needs_agreement": false,
    "profile": {
      "nickname": "닉네임",
      "is_default_nickname": false
    },
    "has_email": true,
    "email_needs_agreement": false,
    "is_email_valid": true,
    "is_email_verified": true,
    "email": "이메일",
    "has_phone_number": true,
    "phone_number_needs_agreement": true,
    "phone_number": "(값이 없거나 동의 필요)"
  }
}

문제점: **has_phone_number: true**이고 **phone_number_needs_agreement: true**인데, 실제 phone_number 값이 비어있거나 전달되지 않습니다.

3. 요청 스코프

현재 OAuth 요청 시 사용하는 스코프:

openid, profile_nickname, account_email, phone_number, name

실제 응답되는 로그를 확인요청 드린 것인데요. 먼저 확인해보시겠어요?

중요 개인정보는 일부 마스킹하시고 출력로그 그대로 첨부 부탁드려요. (호출 시간 확인하여 카카오측 로그와 대조해보겠습니다.)

참고로
id_token 에 추가 개인정보는 포함되지 않으므로 전화번호가 없는 것이 정상동작입니다.

개인정보 ——– 처리했습니다

phone_number값이 없다고 하셨는데, 전달 받으셨네요?