-
NAVER LOGIN API 연동공부일기 2021. 7. 19. 17:01
기본 정보
- Client ID
- Client Secret
- 서비스 URL
- Callback URL
- State
소셜로그인의 과정
소셜로그인의 과정은 크게 3가지로 볼 수 있다.
- 인가코드 받기
- 토큰 받기
- 리소스(회원정보) 받기
- 인가코드 받기
네이버 개발자센터를 통해 서비스를 등록하고, Client ID와 Client Secret을 발급 받는다.
네이버로부터 제공받고자 하는 사용자 정보를 필수, 추가 설정으로 받아올 수 있다.
일단 개발환경에서 테스트할 예정이기 때문에 localhost:8080으로 지정했다.
설정 후 확인을 누르면 네이버에서 Client ID와 Client Secret을 발급해준다.
- Client Secret의 경우 외부에 노출되어선 안 된다.
서비스의 Client ID, redirect_uri(Callback URL의 인코딩 값), state(상태 유지를 위한 임의의 문자열) 정보를 넣어 아래 예제와 같은 주소로 요청을 보낸다.
https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id={}&redirect_uri={}&state={}
로그인하게 되면 아래처럼 필수로 선택해 놓은 항목들을 서비스에 제공하는 데 동의하는 지 묻는다.
동의하기를 누르면 사진처럼 설정해놓은 Callback URL로 이동한다. 이 때 네이버에서 url 파라미터로 code를 제공해주는 것을 확인할 수 있다.
2. 토큰 받기
제공 받은 인가코드(code)를 백엔드쪽에 넘기고, Resource Server(NAVER)에게 토큰을 받아와야 한다.
발급 받은 code와 status 값을 이용해 네이버에게 토큰 발급을 요청한다.
@RequestMapping("/auth/naver/login/callback") public ResponseEntity naverCallback(String code, String state) throws JsonProcessingException { MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("grant_type","authorization_code"); params.add("client_id",CLIENT_ID); params.add("client_secret", CLIENT_SECRET); params.add("code", code); params.add("state", state); // Parameter로 전달할 속성들 추가 HttpEntity<MultiValueMap<String, String>> naverTokenRequest = makeTokenRequest(params); // Http 메시지 생성 RestTemplate rt = new RestTemplate(); ResponseEntity<String> tokenResponse = rt.exchange( TOKEN_REQUEST_URL, HttpMethod.POST, naverTokenRequest, String.class ); // TOKEN_REQUEST_URL로 Http 요청 전송 ObjectMapper objectMapper = new ObjectMapper(); NaverOAuthToken naverToken = objectMapper.readValue(tokenResponse.getBody(), NaverOAuthToken.class); // ObjectMapper를 통해 NaverOAuthToken 객체로 매핑 } private HttpEntity<MultiValueMap<String, String>> makeTokenRequest(MultiValueMap<String, String> params) { HttpHeaders headers = new HttpHeaders(); headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); HttpEntity<MultiValueMap<String, String>> naverTokenRequest = new HttpEntity<>(params, headers); return naverTokenRequest; }
public class NaverOAuthToken { private String access_token; private String refresh_token; private String token_type; private String expires_in; public NaverOAuthToken() { } public String getAccess_token() { return access_token; } ... public void setExpires_in(String expires_in) { this.expires_in = expires_in; } }
3. 리소스 받기(회원정보 받기)
네이버에서 받아온 토큰 정보를 활용해 회원 프로필 조회 API를 호출한다.
응답을 마찬가지로 회원정보 객체에 매핑시킨다.
@RequestMapping("/auth/naver/login/callback") public ResponseEntity naverCallback(String code, String state) throws JsonProcessingException { ... HttpEntity<MultiValueMap<String, String>> naverProfileRequest = makeProfileRequest(naverToken); ResponseEntity<String> profileResponse = rt.exchange( PROFILE_REQUEST_URL, HttpMethod.POST, naverProfileRequest, String.class ); NaverProfileResponse naverProfileResponse = objectMapper.readValue(profileResponse.getBody(), NaverProfileResponse.class); } private HttpEntity<MultiValueMap<String, String>> makeProfileRequest(NaverOAuthToken naverToken) { HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Bearer "+ naverToken.getAccess_token()); headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); HttpEntity<MultiValueMap<String, String>> naverProfileRequest = new HttpEntity<>(headers); return naverProfileRequest; }
public class NaverProfileResponse { private String resultcode; private String message; private NaverProfile response; public NaverProfileResponse() { } public String getResultcode() { return resultcode; } ... public void setResponse(NaverProfile response) { this.response = response; } }
public class NaverProfile { private String email; private String nickname; private String profile_image; private String age; private String gender; private String id; private String name; private String birthday; private String birthyear; private String mobile; public NaverProfile() { } public String getEmail() { return email; } ... public void setMobile(String mobile) { this.mobile = mobile; } }
이후의 과정은
- 서비스 고유의 토큰 생성
- 레이어 분리(컨틀로러-서비스-레파지토리)
등으로 이뤄질 것 같다.
'공부일기' 카테고리의 다른 글
JaCoCo와 SonarQube 연동하기 (0) 2021.08.11 JaCoCo(Java Code Coverage) 적용하기 (0) 2021.08.07 테스트 주도 개발 / 켄트 백 (1) 2021.02.14