소셜 로그인 전 경로(로그인 → 가입 → 계정 연결 → 세션 정리)를 훑어 어디까지 막혀 있는지를 전수로 정리한 표입니다. 2026-09-03 전수 점검으로 만들고 이후 변경을 반영해 왔습니다.
기준일 2026-09-10 · 총 48건
| 기호 | 뜻 |
|---|---|
| 🟢 | 처리됨 + 실기기 확인 |
| 🔵 | 처리됨 + 코드 확인까지 (재현 조건을 만들기 어려움) |
| ⚪ | 의도적으로 처리하지 않음. 사유를 함께 적었다 |
| 상태 | 건수 |
|---|---|
| 🟢 실기기 확인 | 15 |
| 🔵 코드 확인 | 30 |
| ⚪ 의도적 미처리 | 3 |
| 구간 | 건수 |
| --- | --- |
| 1. SDK 단계 | 9 |
| 2. 서버 로그인 단계 | 9 |
| 3. 소셜 가입 단계 | 9 |
| 4. 계정 연결 단계 | 9 |
| 5. 세션 · 로그아웃 | 12 |
재현 조건을 만드는 것이 더 어려운 경우가 많아 코드 확인(🔵)이 절반 이상입니다. 나중에 어디를 다시 검증해야 하는지 알 수 있도록 실측과 코드 확인을 갈라 표시했습니다.
| 엣지케이스 | 처리 | 위치 | 상태 |
|---|---|---|---|
| 사용자가 네이버 로그인을 취소 | isCancel 과 Android user_cancel 코드를 둘 다 본다. 토스트를 띄우지 않는다 |
useNaverLogin.ts |
🟢 |
| 사용자가 애플 로그인을 취소 | 애플은 취소 시 reject 한다. ERR_REQUEST_CANCELED 를 걸러 cancel 로 정규화 |
useAppleLogin.ts |
🟢 |
| 네이버 SDK 가 실패 응답 | isSuccess && successResponse 를 함께 확인해 failure 로 분기 |
useNaverLogin.ts |
🔵 |
애플 identityToken 이 null |
서버가 @NotBlank 라 400 이 난다. 보내지 않고 실패 토스트로 끝낸다 |
login.tsx |
🔵 |
| 네이버 환경변수 미설정 | IS_NAVER_LOGIN_CONFIGURED 로 초기화를 건너뛰고 안내 |
naverLogin.ts |
🔵 |
| 애플 로그인 미지원 기기·OS | isAvailableAsync() 결과로 버튼 자체를 숨긴다 |
login.tsx |
🔵 |
| 버튼 연타 | 서버 왕복 중과 애플 SDK 진행 중에 버튼을 잠근다 | login.tsx |
🟢 |
| 네이버 앱에서 진행하지 않고 돌아옴 | 네이티브가 delegate 콜백이 와야 프로미스를 끝내므로 영영 pending 이다. 그 값으로 버튼을 잠그면 굳어버려 잠금 조건에서 뺐다. 네이티브가 대기를 매 호출마다 덮어써서 다시 눌러도 안전하다 | login.tsx |
🟢 |
| iOS 시뮬레이터에서 네이버 로그인 | 지원하지 않는다. disableNaverAppAuthIOS: false 로 네이버 앱 인증을 쓰기 때문. 실기기로 테스트한다 |
naverLogin.ts |
⚪ |
POST /auth/social-login서버 경로는 5개입니다 — 이미 연결 / 30일 내 해제된 계정(재연결 후보) / 이메일 일치 + 검증됨 / 이메일 일치 + 미검증 / 매칭 없음(신규). 응답 형태는 2개(login, linkCandidate)뿐이고, profileRequired 는 서버가 주는 값이 아니라 앱이 hasProfile 로 갈라냅니다.
| 엣지케이스 | 처리 | 위치 | 상태 |
|---|---|---|---|
| 이미 연결된 계정 | 그대로 로그인. 앱은 라우팅하지 않고 Stack.Protected 에 맡긴다 |
useSocialLogin.ts |
🟢 |
| 이메일 일치 + 소셜쪽 검증됨 | 서버가 자동 병합 후 로그인 | 서버 | 🟢 |
| 이메일 일치 + 소셜쪽 미검증 | linkCandidate → 계정 연결 화면 |
login.tsx → link-social.tsx |
🔵 |
| 신규 유저 | profileRequired → 소셜 가입 화면. 토큰이 저장돼도 GUEST 라 me() 가 403 이므로 탭으로 튕기지 않는다 |
login.tsx → sns-signup/step1 |
🟢 |
| 소셜 토큰 무효·만료 | INVALID_SOCIAL_LOGIN_TOKEN 을 분기해 "다시 시도해주세요" 로 안내 |
login.tsx |
🔵 |
| 30일 이내 해제한 계정으로 재로그인 | 서버가 linkCandidate 로 돌려준다(2026-09-04 신규). 신규 가입이 아니라 연결 화면으로 간다 |
서버 | 🔵 |
maskedEmail 이 null |
재연결 경로에서 이전 계정 이메일을 못 찾는 경우다. 이메일을 언급하지 않는 문구로 갈라 쓴다 | link-social.tsx |
🔵 |
| 네트워크 끊김 | getNetworkErrorMessage 로 에러 코드보다 먼저 걸러낸다 |
login.tsx |
🔵 |
| 그 외 서버 오류 | 일반 실패 토스트 | login.tsx |
🔵 |
POST /user/sns-sign-up| 엣지케이스 | 처리 | 위치 | 상태 |
|---|---|---|---|
| 닉네임 중복 | 중복확인 버튼. nickname-check 는 permitAll 이라 GUEST 도 호출된다 |
sns-signup/step1 |
🟢 |
| 중복확인 후 닉네임을 고침 | 확인을 통과한 닉네임 문자열을 기억하고 현재 입력값과 비교한다. 값이 달라지면 확인 상태가 저절로 풀린다. 입력을 잠그지 않는다 | sns-signup/step1 |
🔵 |
| 확인과 제출 사이에 선점당함 | ALREADY_EXISTS_NICKNAME 을 분기하고 step1 로 되돌린다. 닉네임을 고치면 확인 상태가 풀리고 다시 확인할 수 있다 |
sns-signup/step2 |
🔵 |
termsId 가 실제와 다름 |
NOT_FOUND_TERMS 를 분기. 문구에 "약관" 을 남겨 로그만으로 원인을 알 수 있게 했다 |
sns-signup/step2 |
🔵 |
| 필수 약관 미동의 · 유형 미선택 | 버튼 disabled 로 제출 자체를 막는다 |
step1, step2 |
🟢 |
| 제출 중복 탭 | isSigningUp 을 disabled 에 건다 |
sns-signup/step2 |
🔵 |
| 가입 도중 이탈 | 토큰을 지우지 않는다. 다시 소셜 로그인하면 서버가 hasProfile=false 를 주어 같은 화면으로 돌아온다 |
설계 | 🟢 |
| 가입 성공 후 라우팅 | useSnsSignUp 이 새 USER 토큰으로 GUEST 토큰을 덮어쓰고 me() 를 invalidate 한다 |
useSnsSignUp.ts |
🟢 |
| 네트워크 끊김 | 닉네임 확인·제출 양쪽에 판별 추가 | step1, step2 |
🔵 |
⚠️ 2026-09-09 정정. 이전 판은 위 표의 "중복확인 후 닉네임을 고침" · "확인과 제출 사이에 선점당함" 두 줄을 "입력을 잠근다 / 돌아가면 잠금이 풀린다" 로 적었는데, 둘이 합쳐져 빠져나올 수 없는 상태를 만들고 있었습니다. 입력이 잠긴 채 중복확인 버튼도 같은 조건에서 비활성이라 닉네임을 바꿀 수단이 전부 사라졌고, 되돌아가도 이전 화면이 마운트된 채 남아 잠금이 풀리지 않았습니다. 실기기에서 가입이 막혀서 발견했습니다.
되돌아가면 상태가 초기화된다고 가정하지 않습니다.
POST /auth/social-accounts/link| 엣지케이스 | 처리 | 위치 | 상태 |
|---|---|---|---|
linkToken 5분 만료 |
EXPIRED_OR_INVALID_LINK_TOKEN → 안내 후 로그인 화면으로 되돌린다. 같은 토큰으로는 재시도해도 소용없다 |
link-social.tsx |
🔵 |
| 그 사이 다른 계정에 연결됨 | ALREADY_LINKED_SOCIAL_ACCOUNT → 안내 |
link-social.tsx |
🔵 |
| 이 계정에 같은 provider 가 이미 연결됨 | ALREADY_CONNECTED_PROVIDER → 안내. 2026-09-04 서버 변경으로 연결 확정 API 에도 이 검사가 붙었다 |
link-social.tsx |
🔵 |
| 연결 대상이 이메일 미검증 계정 | REQUIRED_EMAIL_VERIFICATION → 안내 |
link-social.tsx |
🔵 |
| 본인 확인 로그인 실패 | NOT_MATCH_USERNAME_PASSWORD 를 분기해 "이메일과 비밀번호를 확인해주세요" |
link-social.tsx |
🔵 |
| 로그인은 됐는데 연결에서 실패 | 방금 저장한 토큰을 되돌린다. 로그인만 된 중간 상태로 들여보내면 왜 연결이 안 됐는지 모른 채 넘어간다 | useLinkSocialAccount.ts |
🔵 |
| 연결 도중 화면이 사라짐 | 로그인 → 연결 → me() invalidate 순서를 한 mutation 안에서 고정했다. 기존 로그인 훅을 그대로 쓰면 로그인 즉시 화면이 걷힌다 |
useLinkSocialAccount.ts |
🔵 |
| 임시 비밀번호 계정 | requirePasswordChange 면 기존 로그인과 동일하게 변경 화면으로 |
useLinkSocialAccount.ts |
🔵 |
연결 화면 직접 진입 (linkToken 없음) |
안내 후 되돌린다 | link-social.tsx |
🔵 |