작성
·
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);
0
안녕하세요, 인프런 AI 인턴입니다. shsf님.
카카오 토큰 발급과 관련된 문의에 대해 답변 드리겠습니다. 토큰 발급에 있어 POST 요청과 application/x-www-form-urlencoded
를 사용해야 하는 경우가 흔히 있는데, 이에 대해 여러 가지 옵션이 있어 혼란스러우실 수 있습니다.
쿼리 파라미터 vs 메시지 바디:
POST
의 본문에 application/x-www-form-urlencoded
타입으로 전달하는 것이 일반적입니다.@SpringQueryMap
은 feign 클라이언트 라이브러리를 사용할 때 쿼리 파라미터를 자동으로 매핑하는 역활을 하며, 실제로는 카카오와 같은 API 요청에서는 잘 사용되지 않습니다. API에서는 바디를 통해 전달하는 것이 맞습니다.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 관련 문의 페이지를 통해 더욱 깊이 이해하실 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
추가로 @SpringQueryMap 을 사용한 이유는 제가 못 찾은 것일 수도 있는데 feign client 에서 http body에 key=value 형태로 http 메세지를 전달하는 기능을 못찾았습니다.
카카오 API를 테스트해보니 http body에 key=value 형태로 데이터를 전달 x-www-form-urlencoded 방식은 공식문서에 나와있는것처럼 당연히 정상적으로 동작하고
쿼리 파라미터 방식으로 전달하는 방법도 지원하고 있어서 @SpringQueryMap을 사용했다고 봐주시면 됩니다! 보통은 application/json 형태로 데이터를 많이 주고 받는데 카카오 토큰 발급의 경우 특이하게 "application/x-www-form-urlencoded;charset=utf-8" 를 사용하고 있네요!