spring 서버에서 카카오 서버에게 리소스에 접근권한을 가지는 토큰을 요청할때
기존의 RestTemplate를 사용해왔는데 다른 개발자들의 FeignClient를 사용하여 소셜 로그인을 구현한 코드를 보았는데 훨씬
간결하고 사용하기 편해보였다.
간단한 인터페이스 선언방식을 사용하여 마치 Spring Data Jpa, 혹은 mybatis 의 @mapper 어노테이션을 사용하여 실제 구현코드 없이
구현할 수 있어서 코드 간결성과 유지보수에 용이해보여 프로젝트에 도입하기로 결정했다.
우선 기존의 RestTemplate 로 작성한 코드부터 살펴보고 추후 도입한 FeignClient를 도입한 코드와 비교해 보자.
String kakaoTokenUrl = "https://kauth.kakao.com/oauth/token";
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add("grant_type", "authorization_code");
parameters.add("client_id", kakaoClientId);
parameters.add("redirect_uri", kakaoRedirectUrl);
parameters.add("code", kakaoLogin.getCode());
log.info("parameters = {}", parameters);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("Accept", "application/json");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(parameters, headers);
ResponseEntity<String> response = new RestTemplate().postForEntity(kakaoTokenUrl, request, String.class);
MultiValueMap 객체 사용하여 파라미터에 들어갈 값을 셋팅해주고 그후에 HttpHeaders 객체 까지 셋팅해주고..
RestTemplate 에 postForEntity 함수를 사용하여 url, 바디랑 헤더 , 반환 타입 까지 지정해서 보내주면 서버에서 긴 문자열 하나 받아오는 코드 이다.
단순히 바디에 헤더에 필요한 값을 셋팅하고 접근 토큰을 요청하는 간단한 코드인데 코드가 너무 길지 않은가..?
이제 FeignClient 를 도입한 코드를 살펴보자.
String accessToken = clientService.requestToken(
"authorization_code"
, kakaoClientId
, kakaoRedirectUrl
, loginDto.getCode());
어떤가.. 기존의 RestTemplate 코드를 사용한것보다 훨씬 간결하고 무엇을 하려는 코드인지 훨씬 명확하게 보인다.
clientService의 객체에서 내가 작성한 requestToken 이라는 함수 이름을 통해서 토큰을 요청하는 코드라는것을 알 수 있고
String 값의 accessToken 이라는 변수명으로 카카오에서 특정 리소스에 접근할 수 있는 토큰을 반환받는 코드라는것을
한눈에 확인 할 수있다.
코드 작성에 대한 주어진 정답은 없지만 개발자라면 자신의 코드를 더 다듬고 간결하게 유지하고 싶을 것이다.
이제부터 어떻게 FeignClient를 사용하는 방법을 소개하겠다.
추가로 FeignClient에 대해서 문서를 확인하고 싶다면 아래 링크를 클릭하면 된다.
우선 나의 경우에는 spring-boot 의 2.6.4 버전, maven 으로 관리하고 있다.
https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign
FeignClient 적용하기
- pom.xml 파일에 라이브러리를 추가한다.
spring cloud 의존성을 추가해야하는데 우선 아래의 버전을 확인하고 나에게 맞는 버전의 의존성을 추가해야한다.
maven uri는 다음과 같다. https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign
2. FeignClient를 사용하기 위해 우선 Spring 메인지점에 설정을 해준다.
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
이렇게 @EnableFeignClient 어노테이션을 넣어준다.
3. 이제 거의 인터페이스만 선언한다면 거의 끝나간다 너무 간단하지 않은가..?
@FeignClient(name = "kakao", url = "https://kauth.kakao.com")
public interface KakaoFeignClient {
@GetMapping("/oauth/token")
String getToken(@RequestParam("grant_type") String grantType,
@RequestParam("client_id") String clientId,
@RequestParam("redirect_uri") String redirectUri,
@RequestParam("code") String code);
}
기존의 RestTempalte 사용할때는 Map 객체로 바디에 필요한 값을 넣어주고 HttpHeader 객체에 값을 개발자가 일일이 설정해줘야했는데 지금은 어노테이션 기반으로 정말 간결하게 완성된것을 확인할 수가 있다.
4. ClientService 추가적인 작업을 수행할 수 있도록 코드를 작성한다.
public String requestToken(String grantType, String clientId, String redirectUri, String code) {
return commUtils.extractAccessToken(kakaoFeignClient.getToken(grantType, clientId, redirectUri, code));
}
commUtils 객체에서 extractAccessToken 함수는 긴 문자열 값에서 accessToken 값만 가져오는 작업을 한다.
public String extractAccessToken(String token) {
ObjectMapper objectMapper = new ObjectMapper();
String accessToken = "";
try {
JsonNode jsonNode = objectMapper.readTree(token);
accessToken = jsonNode.get("access_token").asText();
} catch (Exception e) {
//TODO Exception 생성하기
throw new RuntimeException("Token Json 파싱 실패");
}
log.info("get access Token = {}", accessToken);
return accessToken;
}
5. 이제 위에서 봤던 간결한 코드를 컨트롤러에서 호출해서 값을 확인하면 된다.
String accessToken = clientService.requestToken(
"authorization_code"
, kakaoClientId
, kakaoRedirectUrl
, loginDto.getCode());
log.info("accessToken = {}", accessToken);
이제 그외 작업인 카카오 유저의 리소스에 접근할 수 있는 토큰을 가지고 요청하는 코드도 마찬가지로 똑같다.
해당 포스트가 여러분들에게 FeignClient 적용하는데 도움이 되었으면 좋겠다 질문사항 있다면 댓글을 통해 질문을 남겨주길 바란다.
'WEB' 카테고리의 다른 글
HTTP 그게 뭔데! ver1 (0) | 2024.08.05 |
---|---|
[OAuth] [JWT] [Spring] 구글 소셜 로그인 Google Login (0) | 2024.03.01 |
[REACT] dotenv 환경변수 설정, 빌드 환경변수 (0) | 2024.02.15 |
Email 인증 로그인 시스템 구축하기 (0) | 2024.02.13 |
OAuth [JWT] 로그인 인증 시스템 구축 (0) | 2024.02.13 |