728x90
반응형
Spring Boot에서 RestTemplate을 통해 네이버 Open API를 호출하여 사용자 정보 받기
*SNS 간편로그인 - 네이버 API 사용 등록 방법 완료 후 진행(관련 글 참고)
*프로세스는 카카오와 구글 모두 동일
*Swagger3 관련 소스 포함
*자세한 설명 생략
▷ application.properties 설정
#NAVER
naver.client.id="NAVER에서 제공한 Client ID"
naver.client.secret="NAVER에서 제공한 Client Secret"
naver.redirect.uri="NAVER에 설정한 Redirect URI"
▷ naver.html
*로그인 화면(간단히 버튼만 생성)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>네이버 테스트 페이지</title>
</head>
<body>
<div align="center">
<h1>네이버 로그인 테스트</h1><br><br>
<a th:href="
@{https://nid.naver.com/oauth2.0/authorize(
client_id=${clientId},
redirect_uri=${redirectUri},
response_type=${responseType},
state=${state}
)}">
<img src="/images/naver_login_btn.png">
</a>
</div>
</body>
</html>
▷ CmmUtil.java
*공통 유틸리티
/**
* 공통 유틸리티
*/
public class CmmUtil {
/**
*
* Object to String
*
* @param Object
* @return String
* @throws JsonProcessingException
*/
public static String getObjStr(Object obj) throws JsonProcessingException {
return new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.writeValueAsString(obj);
}
}
▷ NaverController.java
*로그인 화면 진입 Controller 생성
/**
* 네이버 TEST Controller
*/
@Controller
@RequestMapping("test")
public class NaverContrller {
@Value("${naver.client.id}")
private String NAVER_CLIENT_ID;
@Value("${naver.redirect.uri}")
private String NAVER_REDIRECT_URI;
@GetMapping("/naver.do")
public String kakaoLogin(Model model){
model.addAttribute("clientId", NAVER_CLIENT_ID);
model.addAttribute("redirectUri", NAVER_REDIRECT_URI);
model.addAttribute("responseType", "code");
model.addAttribute("state", "STATE_STRING");
return "naver";
}
}
▷ LGN1003Controller.java
*Redirect Controller 생성
/**
* 네이버 Login Controller
*/
@Slf4j
@RestController
@RequestMapping("xxxx")
@Tag(name = "LGN", description = "Login Controller")
public class LGN1003Controller {
@Autowired
private LGNService lgnService;
@GetMapping("/naver/login.do")
@Operation(summary = "XXXX-LGN-1003", description = "[네이버] 로그인(Redirect)")
public LGN1003ResVO lgn1003(@Parameter(description = "인가 코드") @RequestParam("code") String code) {
LGN1003ResVO resVO = new LGN1003ResVO();
try {
resVO = lgnService.getLGN1003(code);
log.info("[네이버] 로그인 최종 응답");
log.info(CmmUtil.getObjStr(resVO));
} catch (Exception e) {
}
return resVO;
}
}
▷ LGN1003ResVO.java
*최종 응답 VO
/**
* [네이버] 로그인 응답 VO
*/
@Getter
@Setter
@ToString
@Schema(description = "[네이버] 로그인 응답 VO")
public class LGN1003ResVO extends CmmResVO {
/** 결과 값 */
@JsonProperty("result")
@Schema(description = "결과 값")
public LGN1003VO result;
@Getter
@Setter
@ToString
@Schema(description = "[네이버] 로그인 응답 VO")
public static class LGN1003VO {
@Schema(description = "API 호출 결과 코드")
@JsonProperty("resultcode")
public String resultCode;
@Schema(description = "호출 결과 메시지")
@JsonProperty("message")
public String message;
@Schema(description = "동일인 식별 정보")
@JsonProperty("response")
public Response response;
@Getter
@Setter
@ToString
@Schema(description = "[네이버] 동일인 식별 정보 VO")
public static class Response {
@Schema(description = "동일인 식별 정보는 네이버 아이디마다 고유하게 발급되는 값입니다.")
@JsonProperty("id")
public String id;
@Schema(description = "사용자 별명")
@JsonProperty("nickname")
public String nickname;
@Schema(description = "사용자 이름")
@JsonProperty("name")
public String name;
@Schema(description = "사용자 메일 주소")
@JsonProperty("email")
public String email;
@Schema(description = "성별")
@JsonProperty("gender")
public String gender;
@Schema(description = "사용자 연령대")
@JsonProperty("age")
public String age;
@Schema(description = "사용자 생일(MM-DD 형식)")
@JsonProperty("birthday")
public String birthday;
@Schema(description = "사용자 프로필 사진 URL")
@JsonProperty("profile_image")
public String profileImage;
@Schema(description = "출생연도")
@JsonProperty("birthyear")
public String birthyear;
@Schema(description = "휴대전화번호")
@JsonProperty("mobile")
public String mobile;
@Schema(description = "휴대전화번호의 E.164 형식")
@JsonProperty("mobile_e164")
public String mobileE164;
}
}
}
▷ CmmResVO.java
*공통 응답
/**
* 공통 응답 VO
*/
@Getter
@Setter
@ToString
@Schema(description = "공통 응답 VO")
public class CmmResVO {
/** Result Code */
@JsonProperty("resultCode")
@Schema(description = "Result Code")
public String resultCode = "0000";
/** Result Msg */
@JsonProperty("resultMsg")
@Schema(description = "Result Msg")
public String resultMsg = "성공";
/** Set Result */
public CmmResVO setResCmmResult(String resultCode, String resultMsg) {
this.resultCode = resultCode;
this.resultMsg = resultMsg;
return this;
}
}
▷ LGNService.java
/**
* Login Service
*/
public interface LGNService {
/** [네이버] 로그인 **/
public LGN1003ResVO getLGN1003(String code);
}
▷ LGNServiceImpl.java
/**
* Login ServiceImpl
*
*/
@Service
public class LGNServiceImpl implements LGNService {
@Autowired
private NaverApiService naverApi;
/**
* [네이버] 로그인
*/
@Override
public LGN1003ResVO getLGN1003(String code) {
LGN1003ResVO result = new LGN1003ResVO();
try {
/* [네이버] 토큰 발급 */
NaverOAuthTokenVO token = naverApi.getOAuthToken(code);
/* [네이버] 사용자 정보 조회 */
NaverUserInfoVO userInfo = naverApi.getUserInfo(token.getAccess_token());
/* 사용자 정보 저장 */
/* 응답 값 설정 */
Response response = new Response();
response.setId(userInfo.getResponse().getId());
response.setNickname(userInfo.getResponse().getNickname());
response.setName(userInfo.getResponse().getName());
response.setEmail(userInfo.getResponse().getEmail());
response.setGender(userInfo.getResponse().getGender());
response.setAge(userInfo.getResponse().getAge());
response.setBirthday(userInfo.getResponse().getBirthday());
response.setProfileImage(userInfo.getResponse().getProfileImage());
response.setBirthyear(userInfo.getResponse().getBirthyear());
response.setMobile(userInfo.getResponse().getMobile());
response.setMobileE164(userInfo.getResponse().getMobileE164());
LGN1003VO vo = new LGN1003VO();
vo.setResultCode(userInfo.getResultCode());
vo.setMessage(userInfo.getMessage());
vo.setResponse(response);
result.setResult(vo);
} catch (Exception e) {
}
return result;
}
}
▷ NaverOAuthTokenVO.java
/**
* [네이버] 토큰 발급 응답 VO
*/
@Getter
@Setter
@ToString
@Schema(description = "[네이버] 토큰 발급 응답 VO")
@JsonIgnoreProperties(ignoreUnknown = true)
public class NaverOAuthTokenVO {
@JsonProperty("access_token")
@Schema(description = "접근 토큰, 발급 후 expires_in 파라미터에 설정된 시간(초)이 지나면 만료됨")
public String access_token;
@JsonProperty("refresh_token")
@Schema(description = "갱신 토큰, 접근 토큰이 만료될 경우 접근 토큰을 다시 발급받을 때 사용")
public String refresh_token;
}
▷ NaverUserInfoVO.java
/**
* [네이버] 사용자 정보 조회 응답 VO
*/
@Getter
@Setter
@ToString
@Schema(description = "[네이버] 사용자 정보 조회 응답 VO")
@JsonIgnoreProperties(ignoreUnknown = true)
public class NaverUserInfoVO {
@Schema(description = "API 호출 결과 코드")
@JsonProperty("resultcode")
public String resultCode;
@Schema(description = "호출 결과 메시지")
@JsonProperty("message")
public String message;
@Schema(description = "동일인 식별 정보")
@JsonProperty("response")
public Response response;
@Getter
@Setter
@ToString
@Schema(description = "[네이버] 동일인 식별 정보 VO")
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Response {
@Schema(description = "동일인 식별 정보는 네이버 아이디마다 고유하게 발급되는 값입니다.")
@JsonProperty("id")
public String id;
@Schema(description = "사용자 별명")
@JsonProperty("nickname")
public String nickname;
@Schema(description = "사용자 이름")
@JsonProperty("name")
public String name;
@Schema(description = "사용자 메일 주소")
@JsonProperty("email")
public String email;
@Schema(description = "성별", allowableValues = { "F", "M", "U" })
@JsonProperty("gender")
public String gender;
@Schema(description = "사용자 연령대")
@JsonProperty("age")
public String age;
@Schema(description = "사용자 생일(MM-DD 형식)")
@JsonProperty("birthday")
public String birthday;
@Schema(description = "사용자 프로필 사진 URL")
@JsonProperty("profile_image")
public String profileImage;
@Schema(description = "출생연도")
@JsonProperty("birthyear")
public String birthyear;
@Schema(description = "휴대전화번호")
@JsonProperty("mobile")
public String mobile;
@Schema(description = "휴대전화번호의 E.164 형식")
@JsonProperty("mobile_e164")
public String mobileE164;
}
}
▷ NaverApiService.java
/**
* 네이버 API Service
*
* https://developers.naver.com/docs/login/devguide/devguide.md
*/
public interface NaverApiService {
/** [네이버] 토큰 발급 **/
public NaverOAuthTokenVO getOAuthToken(String code);
/** [네이버] 사용자 정보 조회 **/
public NaverUserInfoVO getUserInfo(String accessToken);
}
▷ NaverApiServiceImpl.java
/**
* 네이버 API ServiceImpl
*
*/
@Slf4j
@Service
public class NaverApiServiceImpl implements NaverApiService {
@Value("${naver.client.id}")
private String NAVER_CLIENT_ID;
@Value("${naver.client.secret}")
private String NAVER_API_SECRET;
@Value("${naver.redirect.uri}")
private String NAVER_REDIRECT_URI;
/**
* [네이버] 토큰 발급
*/
@Override
public NaverOAuthTokenVO getOAuthToken(String code) {
NaverOAuthTokenVO result = new NaverOAuthTokenVO();
try {
log.info("[네이버] 토큰 발급 시작");
if (code == null) {
return result;
}
/* 요청 */
final String uri = "https://nid.naver.com/oauth2.0/token";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // MultiValueMap
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type", "authorization_code");
body.add("client_id", NAVER_CLIENT_ID);
body.add("client_secret", NAVER_API_SECRET);
body.add("redirect_uri", NAVER_REDIRECT_URI);
body.add("code", code);
/* 응답 */
ResponseEntity<String> res = new RestTemplate().postForEntity(uri, new HttpEntity<>(body, headers), String.class);
result = new ObjectMapper().readValue(res.getBody(), NaverOAuthTokenVO.class);
log.info("[네이버] 토큰 발급 종료");
} catch (Exception e) {
}
return result;
}
/**
* [네이버] 사용자 정보 조회
*/
@Override
public NaverUserInfoVO getUserInfo(String accessToken) {
NaverUserInfoVO result = new NaverUserInfoVO();
try {
log.info("[네이버] 사용자 정보 조회 시작");
if (accessToken == null) {
return result;
}
/* 요청 */
final String uri = "https://openapi.naver.com/v1/nid/me";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // MultiValueMap
headers.add("Authorization", "Bearer " + accessToken);
/* 응답 */
ResponseEntity<String> res = new RestTemplate().postForEntity(uri, new HttpEntity<>(headers), String.class);
result = new ObjectMapper().readValue(res.getBody(), NaverUserInfoVO.class);
log.info("[네이버] 사용자 정보 조회 종료");
} catch (Exception e) {
log.error("", e);
}
return result;
}
}
▷ 결과
▷ 관련 글
▷ 참고
728x90
728x90
'▶ Back-End > Java' 카테고리의 다른 글
Get Date Now in String (0) | 2024.11.27 |
---|---|
Null Check and Default Value (0) | 2024.08.20 |
SNS 간편로그인 - 구글 로그인 API 호출 및 사용자 정보 받기 (0) | 2024.07.15 |
SNS 간편로그인 - 카카오 로그인 API 호출 및 사용자 정보 받기 (0) | 2024.07.11 |
RestTemplate Post 요청 보내기 (0) | 2024.07.04 |
댓글