인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

shsf님의 프로필 이미지

작성한 질문수

생산성을 향상시키는 스프링부트 기반의 API 템플릿 프로젝트 구현

카카오 토큰 발급 구현 (2) - 토큰 받기

토큰 발급 관련 문의 드립니다.

작성

·

24

0

강사님 안녕하세요, 
토큰 발급과 관련하여 문의드립니다. :)

 

카카오 토큰 발급 요청 시 공식 문서(POST & Content-Type: application/x-www-form-urlencoded;)에 따라

메시지 바디에 쿼리 파라미터 형식으로 데이터를 전달해야하는 것으로 이해했습니다.

 

1.1. 요청을 받는 카카오 입장에선 데이터가 쿼리 파라미터 형식이라면 아래 두 경우를 모두 처리할 수 있나요?

- URL 쿼리 파라미터에 데이터를 포함해서 전달한 경우

- 메시지 바디에 쿼리 파라미터 형식으로 데이터를 전달한 경우

 

1.2. 1.1.이 맞다면, PostMapping으로 @SpringQueryMap KakaoTokenDto.Request request와 같이 정의한 이유가 무엇일지요?

바디가 아닌 URL 쿼리 파라미터에 데이터를 포함했을 때 이점이나 별도 차이가 있는지요? 아니면 단순 선택사항일지요?

 

2.1. 만약 메시지 바디에 쿼리 파라미터 형식으로 전달하고자 한다면,

토큰 발급에 성공하는 아래 방식 중 어떤 방식이 제일 적절한지와 의견 알 수 있을까요?

 

@PostMapping(value = "/oauth/token", consumes = APPLICATION_FORM_URLENCODED_VALUE)
KakaoTokenResponse requestKakaoToken(@RequestBody KakaoTokenRequest request);

 

@PostMapping(value = "/oauth/token", consumes = APPLICATION_FORM_URLENCODED_VALUE)
KakaoTokenResponse requestKakaoToken(@ModelAttribute KakaoTokenRequest request);

 

@PostMapping(value = "/oauth/token", consumes = APPLICATION_FORM_URLENCODED_VALUE)
KakaoTokenResponse requestKakaoToken(KakaoTokenRequest request);

 

2.2. 2.1.의 KakaoTokenResponse requestKakaoToken(KakaoTokenRequest request)의 경우,

@RequestBody 애노테이션이 생략되어 처리되는게 맞을지요? 어떤 방식에 의해 처리되는지 궁금합니다. 

답변 2

0

구파고님의 프로필 이미지
구파고
지식공유자

안녕하세요! 카카오개발자 센터의 공식 문서에서는 토큰 발급 api 요청 시 content-type을 "application/x-www-form-urlencoded;charset=utf-8" 로 데이터를 전달하라고 되어있습니다.

 

말씀해주신 @RequestBody, @ModelAttribute 등 으로 호출해보시면 아시겠지만 카카오 서버에서 처리할 수 없어서 오류가 발생할 것입니다.

content-type을 "application/x-www-form-urlencoded;charset=utf-8" 로 전달한다는 것을 http 메세지를 아래의 예시처럼 보낸다는 것 입니다.

body 본문을 보시면 쿼리파라미터처럼 key1=value1&key2=value2 처럼 데이터를 보내고 있는데 이 방식이 바로 "application/x-www-form-urlencoded;charset=utf-8" 로 보내는 방식입니다.

 

POST /oauth/token HTTP/1.1

Host: https://kauth.kakao.com

Content-Type: application/x-www-form-urlencoded

 

grant_type=authorization_code&client_id=123456&redirect_uri=http://localhost:8080/oauth/kakao/callback&client_secret=1234&code=123452

 

따라서 카카오 API 서버에서 지원하지 않는 http 메세지 형식으로 보낸다면 해당 서버에서 처리를 하지 못하기 때문에 오류가 발생할 수도 입니다.

 

그리고 예시로 주셨던 코드의 경우 consumes에 APPLICATION_FORM_URLENCODED_VALUE 를 지정해주셨는데 consume의 경우 우리 서버가 받을 contenty-type을 명시합니다.

APPLICATION_FORM_URLENCODED_VALUE은 저희가 카카오로 보낼 데이터 타입이구요!

@PostMapping(value = "/oauth/token", consumes = APPLICATION_FORM_URLENCODED_VALUE)

KakaoTokenResponse requestKakaoToken(@RequestBody KakaoTokenRequest request);

 

아래처럼 카카오 서버로 부터 받는 응답을 application/json으로 수정 후 요청 한다고 했을 때 @RequestBody의 경우 request의 데이터를 http body에 json으로 전달합니다.

@PostMapping(value = "/oauth/token", consumes = "application/json")

KakaoTokenResponse requestKakaoToken(@RequestHeader("Content-Type") String contentType, @RequestBody KakaoTokenRequest request);

http 메세지는 아래 예시처럼 전송이 될 것입니다. 이번에는 http body의 데이터 형식이 key1=value1 형식이 아니라 json으로 전송이 될 것이고 카카오 서버에서는 "application/x-www-form-urlencoded" 형태로 데이터를 보내라고 했는데 저희가 마음대로 데이터를 json 형식으로 보내게 된것이구요! 그래서 해당 서버가 메세지를 정상적으로 읽을 수 없어서 오류가 발생할 것 입니다.

 

POST /oauth/token HTTP/1.1

Host: https://kauth.kakao.com

Content-Type: application/json

 

{

"grant_type": "authorization_code",

"client_id": "123123123123",

"redirect_uri": "http://localhost:8080/oauth/kakao/callback",

"code": "123123123123123",

"client_secret": "3124123123123"

}

 

@ModelAttribute와 아무 어노테이션도 사용하지 않고 보냈을 때는 둘다 json 형태로 데이터를 전달하는 것으로 로그를 확인했고 application/json은 카카오 토큰 발급 api에서 처리할 수 없어서 오류가 발생했습니다.

@PostMapping(value = "/oauth/token", consumes = "application/json")

KakaoTokenResponse requestKakaoToken(@ModelAttribute KakaoTokenRequest request);

 

@PostMapping(value = "/oauth/token", consumes = "application/json")

KakaoTokenResponse requestKakaoToken(KakaoTokenRequest request);

 

구파고님의 프로필 이미지
구파고
지식공유자

추가로 @SpringQueryMap 을 사용한 이유는 제가 못 찾은 것일 수도 있는데 feign client 에서 http body에 key=value 형태로 http 메세지를 전달하는 기능을 못찾았습니다.

 

카카오 API를 테스트해보니 http body에 key=value 형태로 데이터를 전달 x-www-form-urlencoded 방식은 공식문서에 나와있는것처럼 당연히 정상적으로 동작하고

image.png

 

쿼리 파라미터 방식으로 전달하는 방법도 지원하고 있어서 @SpringQueryMap을 사용했다고 봐주시면 됩니다! 보통은 application/json 형태로 데이터를 많이 주고 받는데 카카오 토큰 발급의 경우 특이하게 "application/x-www-form-urlencoded;charset=utf-8" 를 사용하고 있네요!

image.png


shsf님의 프로필 이미지
shsf
질문자

강사님 큰 도움 되었습니다, 감사합니다! :)

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. shsf님.

카카오 토큰 발급과 관련된 문의에 대해 답변 드리겠습니다. 토큰 발급에 있어 POST 요청과 application/x-www-form-urlencoded를 사용해야 하는 경우가 흔히 있는데, 이에 대해 여러 가지 옵션이 있어 혼란스러우실 수 있습니다.

  1. 쿼리 파라미터 vs 메시지 바디:

    • 카카오는 메시지 바디에 쿼리 파라미터 형식으로 데이터를 전달하는 것을 권장하며, 이 방식으로 요청을 처리합니다. URL 쿼리 파라미터에 포함하는 것보다 POST 의 본문에 application/x-www-form-urlencoded 타입으로 전달하는 것이 일반적입니다.
    • @SpringQueryMap은 feign 클라이언트 라이브러리를 사용할 때 쿼리 파라미터를 자동으로 매핑하는 역활을 하며, 실제로는 카카오와 같은 API 요청에서는 잘 사용되지 않습니다. API에서는 바디를 통해 전달하는 것이 맞습니다.
  2. PostMapping 방식 선택:

    • @PostMapping(value = "/oauth/token", consumes = APPLICATION_FORM_URLENCODED_VALUE)의 경우 메시지 바디로 데이터를 전달할 때는 일반적으로 @ModelAttribute를 사용합니다.
    • @ModelAttribute는 데이터가 폼 데이터이거나 쿼리 스트링이 필요할 때 주로 사용되며, application/x-www-form-urlencoded로 요청하는 경우 이 선택이 맞습니다.
    • @RequestBody는 JSON 형식의 데이터를 파싱해주는 역할로, 폼의 경우에는 적절하지 않을 수 있습니다.
    • requestKakaoToken(KakaoTokenRequest request)@ModelAttribute를 생략한 단순한 방식으로 처리될 수 있으며, Spring은 자동으로 폼 데이터를 바인딩해줍니다.

다양한 방식들이 있으나, 일반적인 적용 순서 및 방법은 다음과 같습니다. @ModelAttribute를 사용하는 것이 카카오의 application/x-www-form-urlencoded 요청 방식에 가장 부합합니다.

아무쪼록 올바른 방향으로 프로젝트를 진행하시는데에 도움이 되기를 바라며, Feign 클라이언트와 Content-Type 관련 문의 페이지를 통해 더욱 깊이 이해하실 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

shsf님의 프로필 이미지

작성한 질문수

질문하기