[OAuth] 네이버 로그인
현재 OAuth2-Client라는 라이브러리를 사용 중인데 여기에는 Provider가 있다. Provider에는 기본으로 구글, 페이스북, 트위터 등을 제공해 준다. 하지만 네이버나 카카오는 없다.
구글은 sub, 페이스북은 id인 것처럼 getAttribute()의 값이 다양하기 때문에 존재하는 모든 서비스들을 Provider로 제공하기 어렵다.
따라서 네이버 로그인을 이용하기 위해서는 직접 Provider로 등록해줘야 한다.
application.properties (또는 application-oauth.properties)
spring.security.oauth2.client.registration.naver.client-id=Client ID
spring.security.oauth2.client.registration.naver.client-secret=Client Secret
spring.security.oauth2.client.registration.naver.scope=name,email
spring.security.oauth2.client.registration.naver.client-name=Naver
spring.security.oauth2.client.registration.naver.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.naver.redirect-uri=http://localhost:8080/login/oauth2/code/naver
# 이렇게도 가능
#spring.security.oauth2.client.registration.naver.redirect-uri={baseUrl}/{action}/oauth2/code/{registrationId}
OAuth를 사용하기 위한 방식이 여러가지가 있는데, 우리가 사용하는 방식은 코드를 부여받는 방식이다.

NAVER Developers
네이버 오픈 API들을 활용해 개발자들이 다양한 애플리케이션을 개발할 수 있도록 API 가이드와 SDK를 제공합니다. 제공중인 오픈 API에는 네이버 로그인, 검색, 단축URL, 캡차를 비롯 기계번역, 음
developers.naver.com



이제 naver를 Provider로 등록해줘야 한다.
application.properties(application-oauth.properties)
# naver를 Provider로 등록
spring.security.oauth2.client.provider.naver.authorization-uri=https://nid.naver.com/oauth2.0/authorize
spring.security.oauth2.client.provider.naver.token-uri=https://nid.naver.com/oauth2.0/token
spring.security.oauth2.client.provider.naver.user-info-uri=https://openapi.naver.com/v1/nid/me
# 회원정보를 json으로 받는데 response라는 키값으로 네이버가 리턴해줌
spring.security.oauth2.client.provider.naver.user-name-attribute=response
위의 정보는 문서에서 볼 수 있다.

네이버 로그인 개발가이드 - LOGIN
네이버 로그인 개발가이드 1. 개요 4,200만 네이버 회원을 여러분의 사용자로! 네이버 회원이라면, 여러분의 사이트를 간편하게 이용할 수 있습니다. 전 국민 모두가 가지고 있는 네이버 아이디
developers.naver.com
spring.security.oauth2.client.provider.naver.user-name-attribute=response
위 코드는 아래 링크로 가서
네이버 로그인 개발가이드 - LOGIN
네이버 로그인 개발가이드 1. 개요 4,200만 네이버 회원을 여러분의 사용자로! 네이버 회원이라면, 여러분의 사이트를 간편하게 이용할 수 있습니다. 전 국민 모두가 가지고 있는 네이버 아이디
developers.naver.com
출력결과를 보면 response라는 키 값으로 회원정보를 리턴해주는 것을 알 수 있다.

resultcode, message, response는 최상위필드이다. id, email, age, nickname 등은 response에 속한 하위필드이다. 스프링 시큐리티에선 하위 필드를 명시할 수 없다. 최상위필드들만 user_name으로 지정이 가능하다. 따라서 response를 user_name으로 지정하고 코드로 response 안의 필요한 정보를 가져와야 한다.
loginForm.html
</form>
<a href="/oauth2/authorization/google">구글 로그인</a>
<a href="/oauth2/authorization/facebook">페이스북 로그인</a>
<a href="/oauth2/authorization/naver">네이버 로그인</a>
<a href="/joinForm">회원가입을 아직 하지 않으셨나요?</a>
</body>
</html>
localhost:8080/loginForm으로 가서 네이버 로그인을 해보자

아직은 아래와 같은 오류가 뜬다

이유는 PrincipalOauth2UserService에 네이버 로그인 기능을 구현하지 않았기 때문이다.
PrincipalOauth2UserService
...
if (userRequest.getClientRegistration().getRegistrationId().equals("facebook")) {
System.out.println("페이스북 로그인 요청");
oAuth2UserInfo = new FacebookUserInfo(oAuth2User.getAttributes());
}
if (userRequest.getClientRegistration().getRegistrationId().equals("naver")) {
System.out.println("네이버 로그인 요청");
oAuth2UserInfo = new NaverUserInfo((Map)oAuth2User.getAttributes().get("response"));
}
String provider = oAuth2UserInfo.getProvider();
String providerId = oAuth2UserInfo.getProviderId();
String username = provider + "_" + providerId;
String password = bCryptPasswordEncoder.encode("아무거나");
String email = oAuth2UserInfo.getEmail();
String role = "ROLE_USER";
...
NaverUserInfo
package com.cos.security.config.oauth.provider;
import lombok.RequiredArgsConstructor;
import java.util.Map;
@RequiredArgsConstructor
public class NaverUserInfo implements OAuth2UserInfo{
private final Map<String, Object> attributes; // oauth2User.getAttributes()
@Override
public String getProviderId() {
return (String) attributes.get("id");
}
@Override
public String getProvider() {
return "naver";
}
@Override
public String getEmail() {
return (String) attributes.get("email");
}
@Override
public String getName() {
return (String) attributes.get("name");
}
}
이제 다시 네이버 로그인을 하면 로그인이 되고 가입도 잘 되었다.
