[Spring] Authorization code Grant 4 - 네이버 로그인

류재성's avatar
Jun 10, 2024
[Spring] Authorization code Grant 4 - 네이버 로그인
 

1. 기본 설정

 

1.1 네이버 개발자 센터

 
 
notion image
 

1.2 내 애플리케이션 만들기

 
notion image
 
notion image
 
제공 정보 선택 등록을 한다.
 
notion image
💡
API 의 환경을 등록한다. 현재는 웹 서버라서 PC앱을 선택한다.
 
 
notion image
notion image
 
컨트롤러에 콜백 API 를 만든 후 Callback URL 에 등록한다.
 
 
notion image
 
등록하면 Client ID 와 Client Secret 을 확인할 수 있다.
 

2. 네이버 서버에 API 요청하기

 

2.1 네이버 로그인

https://nid.naver.com/oauth2.0/authorize //GET요청
 
notion image
 
notion image
https://nid.naver.com/oauth2.0/authorize?client_id={내 클라이언트ID}&response_type=code&redirect_uri=http://localhost:8080/oauth/naver/callback&state=$2a$10$M119OnzkM1HHpZLCDIhrne4mYR9bwQWvRoHXvZMfh1Yxamf8UbmHq
💡
state 는 UUID 로 만든 임의이 난수를 입력하면 된다.
notion image
notion image
 
주소를 입력했을 때 Redirect_uri가 정상적으로 호출되었다. CODE도 확인할 수 있다.
 
notion image
 
이 주소를 a태그 주소에 넣는다.
 

2.2 토큰 받기

https://nid.naver.com/oauth2.0/token //POST 요청
notion image
 
notion image
 
notion image
토큰을 정상적으로 발급 받았다.
 
NaverResponse
package org.example.loginapp.user; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; public class NaverResponse { @Data public static class TokenDTO{ @JsonProperty("access_token") private String accessToken; @JsonProperty("refresh_token") private String refreshToken; @JsonProperty("token_type") private String tokenType; @JsonProperty("expires_in") private String expiresIn; } }
포스트맨으로 확인한 JSON 형태로 DTO를 만든다.
 

2.3 네이버 회원 프로필 조회

https://openapi.naver.com/v1/nid/me //GET 요청
notion image
 
notion image
💡
토큰을 보낼때 Bearer 한칸 띄우고 토큰을 보내야 한다.
 
notion image
 
NaverResponse
@Data public static class NaverUserDTO { private String resultcode; private String message; private ResponseDTO response; @Data class ResponseDTO { private String id; private String email; } }
 
네이버에서 받은 회원 정보를 담는 DTO 를 만든다.
 

3. 토큰 검증 후 로그인(혹은 회원가입)

 
UserService
public User 네이버로그인(String code) { // 1. code로 카카오에서 토큰 받기 (위임완료) - oauth2.0 // 1.1 RestTemplate 설정 RestTemplate rt = new RestTemplate(); // 1.2 http header 설정 HttpHeaders headers = new HttpHeaders(); headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); // 1.3 http body 설정 MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); body.add("grant_type", "authorization_code"); body.add("client_id", "wkI_0iNs7BmVF5O9ZLr1"); body.add("client_secret", "oCftA1myO0"); body.add("code", code); body.add("state", UUID.randomUUID().toString()); // 1.4 body+header 객체 만들기 HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers); // 1.5 api 요청하기 (토큰 받기) ResponseEntity<NaverResponse.TokenDTO> response = rt.exchange( "https://nid.naver.com/oauth2.0/token", HttpMethod.POST, request, NaverResponse.TokenDTO.class); // 1.6 값 확인 System.out.println(response.getBody().toString()); // // 2. 토큰으로 사용자 정보 받기 (PK, Email) HttpHeaders headers2 = new HttpHeaders(); headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); headers2.add("Authorization", "Bearer " + response.getBody().getAccessToken()); HttpEntity<MultiValueMap<String, String>> request2 = new HttpEntity<>(headers2); ResponseEntity<NaverResponse.NaverUserDTO> response2 = rt.exchange( "https://openapi.naver.com/v1/nid/me", HttpMethod.GET, request2, NaverResponse.NaverUserDTO.class); System.out.println("response2 : " + response2.getBody().toString()); // 3. 해당정보로 DB조회 (있을수, 없을수) String username = "Naver_" + response2.getBody().getResponse().getId(); User userPS = userRepository.findByUsername(username); // 4. 있으면? - 조회된 유저정보 리턴 if (userPS != null) { System.out.println("회원 정보 있음. 강제로그인 진행"); return userPS; } else { System.out.println("회원 정보 없음. 강제회원가입 and 강제로그인 진행"); // 5. 없으면? - 강제 회원가입 // 유저네임 : (provider_pk) // 비밀번호 : UUID // 이메일 : email 받은 값 User user = User.builder() .username(username) .password(UUID.randomUUID().toString()) .email(response2.getBody().getResponse().getEmail()) .provider("naver") .build(); User returnUser = userRepository.save(user); return returnUser; } }
 
 
notion image
로그인이 완료되었다.
 
notion image
 
DB에서도 데이터가 입력된 것을 볼 수 있다.
Share article
RSSPowered by inblog