ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • NAVER LOGIN API 연동
    공부일기 2021. 7. 19. 17:01

    기본 정보

    • Client ID
    • Client Secret
    • 서비스 URL
    • Callback URL
    • State

     

    소셜로그인의 과정

    소셜로그인의 과정은 크게 3가지로 볼 수 있다.

    1. 인가코드 받기
    2. 토큰 받기
    3. 리소스(회원정보) 받기
    4. 인가코드 받기

    네이버 개발자센터를 통해 서비스를 등록하고, 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
Designed by Tistory.