카카오 로그인 토큰 받기
문제
카카오 로그인 중 2단계에 해당하는 토큰을 받아오는 과정에서 axios로는 정상적으로 받아오는데 fetch로는 받아오지 못하는 문제가 발생했다.
처음에 fetch를 사용했던 방법은
const url = `https://kauth.kakao.com/oauth/token`
const body = {
grant_type: 'authorization_code',
client_id: process.env.REST_API as string,
redirect_uri: process.env.REDIRECT as string,
code,
}
const result = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
},
body: JSON.stringify(body),
})
const data = await result.json()
을 사용했다.
하지만 이 방법은 아래와 같은 오류(KOE010)를 발생했다.
{
error: 'invalid_client',
error_description: 'Bad client credentials',
error_code: 'KOE010'
}
카카오 로그인 공식 문서를 보면 해당 오류는 클라이언트 시크릿(Client secret) 기능을 사용하는 앱에서 토큰 요청 시 client_secret 값을 누락했거나 잘못된 값을 전달한 경우
발생한다고 한다.
하지만 나는 클라이언트 시크릿 기능을 활성화하지 않은 상태이기 때문에 이 오류가 발생할 수 없다.
다른 방법
axios로 요청을 보내는 방법을 사용했더니 정상적으로 토큰을 받아왔다. 그래서 axios와 fetch의 차이점을 찾아보았다.
차이점
Content-Type과 요청 본문의 형식
카카오 API는 일반적으로 application/x-www-form-urlencoded 형식의 데이터로 요청을 받는다. axios를 사용할 때, 요청 본문은 자동으로 application/x-www-form-urlencoded 형식으로 변환됩니다. headers에서 설정한 Content-Type과 일치합니다.
반면, fetch를 사용할 때는 JSON.stringify(body)를 사용하여 요청 본문을 JSON 형식으로 변환합니다. 그러나 headers에서 설정한 Content-Type은 application/x-www-form-urlencoded이다.
그래서 형식이 맞지 않아 오류가 발생한 것이다. 형식을 맞춰 주기 위해서 fetch를 사용할 때는 URLSearchParams를 사용하여 요청 본문을 application/x-www-form-urlencoded 형식으로 변환해주어야 한다.
어떻게 보면 너무 어이없는 실수를 한 것 같다.
해결
- axios 방식
const url = `https://kauth.kakao.com/oauth/token`
const body = {
grant_type: 'authorization_code',
client_id: process.env.REST_API as string,
redirect_uri: process.env.REDIRECT as string,
code,
}
const {data} = await axios.post(
url,
{
grant_type: 'authorization_code',
client_id: process.env.REST_API as string,
redirect_uri: process.env.REDIRECT as string,
code,
},
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
},
},
)
- fetch 방식
const url = `https://kauth.kakao.com/oauth/token`
const fetchBody = new URLSearchParams({
grant_type: 'authorization_code',
client_id: process.env.REST_API as string,
redirect_uri: process.env.REDIRECT as string,
code,
})
const result = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
},
body: fetchBody,
})
const data = await result.json()
'시작 > TIL(Today I Learned)' 카테고리의 다른 글
브라우저 탭간 통신하기 : BroadCast Channel API ( feat. Next.js) (0) | 2024.01.16 |
---|---|
StyleXjs : StyleX 세팅 및 기초 (feat. NEXT) (1) | 2023.12.26 |
231109 - Monorepo를 이용한 Next.js 프로젝트 구성하기 (feat. pnpm) (1) | 2023.11.09 |
231010 - NextJS 클라이언트에서 S3 업로드 (1) | 2023.10.11 |
230925 - React 컴포넌트의 유연성과 최적화 ( 조건부 렌더링, 다이나믹 컴포넌트, 고차컴포넌트(HOC)) (0) | 2023.09.25 |
댓글