[트러블슈팅] OAuth2 Github 이메일이 `null`일 수도 있다!

wannabeing·2025년 6월 5일
2

SPARTA-TIL

목록 보기
23/23
post-thumbnail

이슈 발생

  • 다른 사람들: GitHub 소셜 로그인이 동작은 하는데, 이메일 정보가 null이다.
  • 나: 나는 되는데??

우리는 메일이 꼭 필요하다.. 꼭 구현해내리라


원인

Github 계정 - Settings - Email 탭에서 Primary 이메일이 없거나,
private 설정이 되어있으면 이메일을 가져올 수가 없는 것 같다!


해결방법

깃허브로부터 발급받은 accessToken을 이용해서 유저 정보를 가져올 수 있다.

https://api.github.com/user/emails
- Header Authorization Bearer USER_TOKEN

이메일 가져오는 API를 한번 더 호출하는 것이다!


추가 작성 코드

// OAuth2UserRequest에서 accessToken 가져오기
String accessToken = userRequest.getAccessToken().getTokenValue();

// 이메일 가져오는 메서드
public String getEmail() {
	try {
		String attributeEmail = (String) attributes.get("email");
		return attributeEmail != null ? attributeEmail : fetchEmailWithAccessToken(accessToken);
	} catch (Exception e){
		throw new OAuth2Exception(OAuth2ExceptionCode.SOCIAL_EMAIL_NOT_FOUND);
	}
}

/**
 * public 이메일이 없을 경우, accessToken을 사용하여 이메일을 반환하는 메서드
 * @param accessToken 사용자 액세스 토큰
 * @return private 사용자 이메일을 반환
 */
private String fetchEmailWithAccessToken(String accessToken) {
	WebClient webClient = WebClient.builder()
		.baseUrl("https://api.github.com")
		.defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)
		.defaultHeader(HttpHeaders.ACCEPT, "application/vnd.github.v3+json")
		.build();

	List<Map<String, Object>> emails = webClient.get()
		.uri("/user/emails")
		.retrieve()
		.bodyToMono(new ParameterizedTypeReference<List<Map<String, Object>>>() {})
		.block();

	if (emails != null) {
		for (Map<String, Object> emailEntry : emails) {
			if (Boolean.TRUE.equals(emailEntry.get("primary")) && Boolean.TRUE.equals(emailEntry.get("verified"))) {
				return (String) emailEntry.get("email");
			}
		}
	}
	throw new OAuth2Exception(OAuth2ExceptionCode.SOCIAL_EMAIL_NOT_FOUND_WITH_TOKEN);
}
  • 먼저 public 이메일이 있으면 해당 이메일을 반환한다.
  • public 이메일이 없다면 fetchEmailWithAccessToken() 메서드를 실행한다.
  • WebClient를 통해서 API 요청을 날리고, emails 배열에서 대표&인증받은 이메일을 반환한다.

❓ WebClient

  • 스프링에서 제공하는 HTTP 요청을 만드는 라이브러리
  • 반응형(Reactive)으로 설계되어 있어 비동기(Async), 비차단(Non-Blocking) 통신을 효율적으로 처리할 수 있다고 한다.

출처

https://uhanuu.tistory.com/entry/OAuth-20-GitHub-이메일-null이슈
https://vesselsdiary.tistory.com/192
https://github.com/nextauthjs/next-auth/issues/374

profile
wannabe---ing

0개의 댓글