Skip to content

fix: custom OAuth2 provider returns "missing provider id" when userinfo lacks sub field (#2519)#2528

Open
mrigangha wants to merge 3 commits into
supabase:masterfrom
mrigangha:fix/custom-oauth-missing-provider-id
Open

fix: custom OAuth2 provider returns "missing provider id" when userinfo lacks sub field (#2519)#2528
mrigangha wants to merge 3 commits into
supabase:masterfrom
mrigangha:fix/custom-oauth-missing-provider-id

Conversation

@mrigangha

@mrigangha mrigangha commented May 13, 2026

Copy link
Copy Markdown

What kind of change does this PR introduce?

Bug fix #2519

What is the current behavior?

When using a custom OAuth2 provider whose userinfo endpoint returns id instead of sub, the authentication flow fails with:
error=server_error
error_description=error missing provider id
This happens even when attribute_mapping: { "sub": "id" } is configured, because the mapping is applied after the raw userinfo JSON has already been unmarshaled into the Claims struct — at which point any field not present in Claims (like id) has already been silently dropped.
Additionally, NewIdentity in identity.go only looks for sub in identityData with no fallback, making it fragile for any non-OIDC provider.

What is the new behavior?

1).applyAttributeMapping now runs on the raw userinfo JSON before conversion to Claims, so provider-specific fields like id are preserved and correctly remapped to sub

2).NewIdentity now falls back to identityData["id"] if identityData["sub"] is not present, making it more resilient to non-OIDC providers

Additional context

Files changed:

1).internal/api/provider/custom_oauth.go — apply attribute mapping on raw JSON before Claims conversion, add applyAttributeMappingRaw helper

2).internal/models/identity.go — add id fallback in NewIdentity

@mrigangha mrigangha requested a review from a team as a code owner May 13, 2026 07:07
bewannabe96 added a commit to bewannabe96/claim-web that referenced this pull request Jun 18, 2026
`missing provider id` 의 진짜 원인은 PKCE·네이티브가 아니라, GoTrue 가 custom provider
userinfo 응답에서 식별자(sub)를 못 뽑는 것(supabase/auth#2528) — 네이버 /v1/nid/me 가 id 를
표준 top-level sub 가 아니라 response 안에 중첩해 주기 때문. 세션 mint(B)는 과한 우회였다.

- 폐기: POST /api/app/v1/auth/naver/session + service_role admin mint(supabase-admin.ts,
  SUPABASE_SECRET_KEY, 합성 이메일). 세션은 GoTrue 가 custom provider 로 직접 발급.
- 신설: GET /api/auth/naver/userinfo (모바일 프리픽스 밖, GoTrue 가 호출). 네이버 토큰을
  Bearer 로 받아 /v1/nid/me 검증 → 중첩 response.id 를 top-level sub 로 평탄화해 {sub,email?,name?}.
- 브링업 검증 로깅 토글 NAVER_USERINFO_DEBUG (기본 off — 첫 배포 확인 후 끔).
- ADR-0035 재작성(세션 mint → userinfo 프록시), 폐기된 web-mobile-studio-api.md 제거.
- 앱 변경 0/새 빌드 0 — signInWithOAuth('custom:naver') 그대로, UserInfo URL 만 대시보드 변경(owner).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bewannabe96 added a commit to bewannabe96/claim-web that referenced this pull request Jun 18, 2026
* feat(auth): 네이버 소셜 백엔드 세션 엔드포인트 — POST /auth/naver/session (ADR-0035)

네이버는 Supabase 내장 provider 가 아니라(카카오·애플과 달리), A 경로(Custom OAuth
Provider)가 업스트림 버그 supabase/auth#2519 + PKCE 로 모바일에서 막힘. B 경로로 전환 —
앱이 네이티브 SDK 로 받은 네이버 accessToken 을 백엔드가 검증 후 Supabase 세션으로 교환.

- POST /api/app/v1/auth/naver/session (인증 none) — body 토큰이 자격증명, 서버가 nid/me 검증.
- 식별 키 = 네이버 response.id(불변) — 이메일 아님. auth 유저는 네이버 id 파생 합성 이메일로 키잉.
- 세션 mint = service_role admin createUser → generateLink(magiclink) → verifyOtp 교환.
  신규 SUPABASE_SECRET_KEY + server/supabase-admin.ts (RLS 우회 격리, auth 세션 외 사용 금지).
- 계정 연결: 네이버 = 별개 auth 신원(카카오·애플 동일). 동일인 병합은 phone(본인인증) UNIQUE 가 담당.
- 계약 정본 docs/web-mobile-studio-api.md(신설, claim-web owner) + ADR-0035. 4건 owner 확정.
- 안전: .claude/secrets.env / sprint-state.json gitignore 추가(봇 토큰 커밋 방지).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(auth): 네이버 세션 mint → userinfo 프록시 전환 (위임 정정, ADR-0035)

`missing provider id` 의 진짜 원인은 PKCE·네이티브가 아니라, GoTrue 가 custom provider
userinfo 응답에서 식별자(sub)를 못 뽑는 것(supabase/auth#2528) — 네이버 /v1/nid/me 가 id 를
표준 top-level sub 가 아니라 response 안에 중첩해 주기 때문. 세션 mint(B)는 과한 우회였다.

- 폐기: POST /api/app/v1/auth/naver/session + service_role admin mint(supabase-admin.ts,
  SUPABASE_SECRET_KEY, 합성 이메일). 세션은 GoTrue 가 custom provider 로 직접 발급.
- 신설: GET /api/auth/naver/userinfo (모바일 프리픽스 밖, GoTrue 가 호출). 네이버 토큰을
  Bearer 로 받아 /v1/nid/me 검증 → 중첩 response.id 를 top-level sub 로 평탄화해 {sub,email?,name?}.
- 브링업 검증 로깅 토글 NAVER_USERINFO_DEBUG (기본 off — 첫 배포 확인 후 끔).
- ADR-0035 재작성(세션 mint → userinfo 프록시), 폐기된 web-mobile-studio-api.md 제거.
- 앱 변경 0/새 빌드 0 — signInWithOAuth('custom:naver') 그대로, UserInfo URL 만 대시보드 변경(owner).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom OAuth (oauth2) returns "missing provider id" after successful login

1 participant