공부일지/프로젝트
[트러블 슈팅] OAuth2 플랫폼 별 Email 같을 때 다른계정으로 로그인 되는 문제
박수빈98
2025. 7. 18. 16:36
Refresh Token을 적용하고 테스트하는 과정에서 다음과 같은 문제 발생하였다.
문제 요약
- A 사용자가 Google로 test@gmail.com 가입
- B 사용자가 Kakao로 동일 이메일로 로그인 시도 → A 계정으로 로그인 처리됨
- 이유: 이메일이 유일한 값으로 설정되어 있어 provider 구분 없이 하나의 계정으로 인식됨
해결 전략
- User 엔티티에 provider 필드(enum)를 추가
- 로그인 시 email + provider 조합으로 비교는 하지 않음
- email만을 기준으로 중복 여부를 판단하고, 이미 존재할 경우 해당 provider 정보를 포함한 에러 응답 반환
API 응답 예시
{
"success": false,
"message": "GOOGLE로 가입된 이메일입니다.",
"data": {
"email": "test@gmail.com",
"provider": "GOOGLE"
},
"errorCode": "U001",
"statusCode": 409,
"timestamp": "..."
}
만약 ID/PW로 일반 회원가입 한 경우는
{
"success": false,
"message": "LOCAL로 가입된 이메일입니다.",
"data": {
"email": "subin4420@gmail.com",
"provider": "LOCAL"
},
"errorCode": "U001",
"statusCode": 409,
"timestamp": "2025-07-18T16:26:04.517582"
}
장점
- 이메일 기준 단일 계정 유지
- 소셜 계정 중복 생성을 방지
- 프론트에서 사용자에게 정확한 로그인 플랫폼 안내 가능
- DB에서 복합키 없이 로직으로 관리 가능
단점
- 탈퇴 후 재가입 시 기존 플랫폼 정보를 사용자가 기억하지 못할 수 있음 → DB에 Provider 저장으로 해결
- 가입 플랫폼 정보를 UI에 표시하지 않으면 사용자가 혼란을 겪을 수 있음 → 응답으로 provider 제공해 어떤 이메일이 어떤 플랫폼으로 가입되었는지 안내
결론
- 하나의 이메일로 하나의 계정만 허용
- 이미 가입된 이메일인 경우, 어떤 플랫폼(provider)으로 가입되어 있는지 명시하여 에러 응답
- provider는 필수로 저장하며, LOCAL(ID/PW)과 소셜 로그인을 구분함
배운 점 정리
- 동일 이메일로 여러 플랫폼 가입을 허용하면 안 되는 이유: 계정 충돌
- provider는 필수 필드이며 null이 아닌 LOCAL, GOOGLE 등으로 명확히 구분
- 중복 가입 방지는 서버 로직으로 처리하고, 복합키 대신 에러 응답 설계로 유연하게 대응