졸업 작품 개발 api 서버 개발에 맞춰 프론트도 request authorization을 준비하고 있던 도중에, SSR로 데이터를 받아오는 detail page에서 cookie에 저장된 token을 받아오지 못하는 오류가 발생하였다.
1. 문제 발생 이유
Next.js의 getServerSideProps 를 이용하여 클라이언트 단이 아닌, Next.js 서버 단에서 api를 호출하고 데이터를 받아오기 때문이다.
쿠키에서 token값을 받아오고 axios interceptor를 통해 매 request마다 authorization header에 bearer token을 담아서 보내주고 있었는데, server side에선 브라우저 내에 저장되어 있는 token을 가져올 수 없기 때문이다.
2. 해결 방법
문제가 쉬운만큼 해결 방법도 매우 쉬웠다.
그냥 api 호출 시 별도로 authorization header에 token을 심어주도록 수정하고, getServerSideProps 에서 api 호출 시 request context에서 cookie를 파싱하고 이 값을 별도로 넣어주었다.
하지만 이때 문제가 하나 더 발생했는데,
// service api
api.get(url, { headers: { Authorization: `Bearer ${token}` }});
수정된 api 호출 함수는 위와 같다면,
// base api interceptor
const withAuth = (instance) => {
const userToken = getCookies("user"); // cookies-next library
instance.interceptor.request.use((config) => {
config.headers["Authorization"] = userToken
? `Bearer ${userToken}`
: "";
return config;
});
return instance;
}
axios interceptor가 위와같이 설정되어 있었다.
따라서, api를 호출하게 되면 정상적으로 token값을 받아오고 헤더에 이를 담아서 요청을 보내려 하지만, interceptor가 작동하여 cookie값인 userToken이 undefined 값이기 때문에 Authorization header 값을 지워버렸다.
어차피 token값을 따로 담아서 api 호출하는 경우는 server side에서 요청을 보내는 경우 밖에 없기 때문에, typeof window를 통해 요청이 서버 사이드에서 오는 요청인지 확인만 하도록 수정해주었다.
// base api interceptor
const withAuth = (instance) => {
// typeof window !== undefined
// Node.js에선 window 객체가 정의되지 않아있기 때문에,
// 이를 통해 server side인지 client side인지 확인이 가능하다.
if (typeof window !== undefined) {
const userToken = getCookies("user"); // cookies-next library
instance.interceptor.request.use((config) => {
config.headers["Authorization"] = userToken
? `Bearer ${userToken}`
: "";
return config;
});
}
return instance;
}
다른 방법도 많았지만, 내 생각엔 이 방법이 깔끔한 것 같아서 이 방법으로 해결했다.
별도로 token을 담아줘야 하는 번거로움이 있지만, 다른 라이브러리나 함수를 사용하는 과정보단 덜 번거로울 것 같았다.