[NextJS/TroubleShooting] - Route Handlers

ZenTechie·2023년 8월 9일
0

Troubleshooting

목록 보기
1/9
post-thumbnail

기존 React로 작업한 Buddies 프로젝트를 NextJS, TypeScript로 마이그레이션 하면서 발생한 오류이다.

현재 사용중인 NextJS 버전은 13이며, App router를 사용하고 있다.

문제 발생

문제가 발생한 곳은, Kakao 로그인의 토큰 받기에서 발생했다.
React에서는 아래와 같이 토큰 받기를 수행한다.

await axios('https://kauth.kakao.com/oauth/token', {
        method: 'post',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        data: `grant_type=authorization_code&client_id=${process.env.NEXT_PUBLIC_KAKAO_REST_KEY}&redirect_uri=${window.location.origin}/kakaotalk&code=${code}`,
      }).then((res: any) => {
        const data = res.data;
        console.log('getKakaoToken data', data);
        console.log('Kakao IdToken', data.id_token);
        console.log('Kakao AccessToken', data.access_token);
      });

NextJS13에서는 Route Handler라는 기능이 있다. 이 기능은 웹 Request, Response API를 사용하는 Route에 대해 커스텀 Request Handler를 만들 수 있게 해준다.

이때 디렉토리 구조는 다음과 같다.

내가 이해한 바로는 app 폴더 내에 api 폴더를 생성하고 api 폴더 내의 route.js에 API를 처리하는 코드를 작성하면 된다고 생각했다.

또한, 여기서 중요한 것은 Route Handler의 이름이 GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS여야 한다는 것이다.

이를 이용해서, 나는 app-api-getLogin-route.js로 디렉토리 구조를 설정했고, 코드는 아래와 같다.

// route.js
export async function POST(
  req: Request,
) {
  const data = await req.json(); // res now contains body
  const code = data.authCode;
  console.log("resis", data);
  const url = `https://kauth.kakao.com/oauth/token/grant_type=authorization_code&client_id=${process.env.NEXT_PUBLIC_KAKAO_REST_KEY}&redirect_uri=http://localhost:3000/kakaotalk&code=${code}`;

  // const response = await fetchLogin(url);
  const response = await fetch(`https://kauth.kakao.com/oauth/token?grant_type=authorization_code&client_id=${process.env.NEXT_PUBLIC_KAKAO_REST_KEY}&redirect_uri=http://localhost:3000/kakaotalk&code=${code}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
    },
  }).then((res) => {
    console.log(res);
    res.json()
  });
  return response;
}

그리고 Route로의 요청 코드는 아래와 같이 작성했다.

await axios('/api/getLogin'), {
  method: 'post',
  ... // 상세 옵션 생략
}

이때 'POST '/api/getLogin' 500 (Internal Server Error) 에러가 발생했다.

원인

App Router 방식으로 작성된 코드가 많지 않아, 정확한 원인은 아직 찾지 못했다.
추측컨대, 현재 Route로의 요청 코드가 Client Component에 작성되서 그런게 아닌가 싶다.

해결

결론적으로 해결은 했는데, Route로의 요청을 수행할 때 경로를 '/api/getLogin'이 아닌, 'https://kauth.kakao.com/oauth/token/'으로 하는 것이었다.

즉, 그냥 Route Handler를 사용하지 않고 직접 POST 요청을 하게 되면 정상적으로 동작한다.

원하는 해결방식은 아닌데 아무리 찾아봐도 App Router 방식에서의 솔루션은 찾아볼 수가 없어서, 일단 이대로 마무리했다.

App Router를 권장한다고 해서, 그렇게 만들었건만... 어째 Pages Router보다 더 어렵게 느껴진다. Document도 뭔가 부족한 것 같고, 구글링해보면 App Router로 작성된 코드가 별로 없어서 참고하기에도 부족하다..

profile
데브코스 진행 중.. ~ 2024.03

1개의 댓글

comment-user-thumbnail
2023년 8월 9일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기