토큰 관리를 클라이언트에서 하기에,
전역적으로 관리할 필요가 있으며, 그 값을 다루는 프레임워크인 Next.js의 위에서 다루게 된다.
Next.js는 기본적으로 서버단으로 부터 페이지를 렌더링 하기 때문에,
클라이언트단 말고도 서버측에서도 토큰을 통합 관리 할 수 있는 기능이 필요하다. 클라이언트단 서버측에서도 관리를 할 수 있게 하면, 데이터를 prefetching 할 수 있는 장점을 통해 사용자 경험을 증진시킬 수 있다.
처음 zustand의 미들웨어로 전역관리를 하기 때문에 서버측(SSR)에서는 전역상태 값을 불러서 다룰 수 없다.
-> sessionStorage, localStorage는 브라우저에 있는 저장 공간이지, 서버측에서도 통용되는 저장공간이 아니기 때문이다.
그렇다면 서버측에서 관리를 위해서는 cookie를 생각 할 수가 있다. (서버와 클라이언트간 서로 주고 받기 위한 매개체 역할을 하니)
document.cookie
를 사용하여 값을 넣어주고,req.cookie
를 사용하여 cookie 값을 불러오고 http 통신을 하면 되기 때문이다. // client
const ClientComponent = ()=>{
const submitHandle = async (value: Schema) => {
console.log(value);
const { data } = await axios.get<PAuth[]>("http://localhost:4000/users");
//...생략
document.cookie = `token=${data.token};`;
}
// 기본적으로 Page Router에서는 default로 SSG이므로 서버측에서부터 렌더링 하기에, document값 자체를 읽지 못한다.
console.log(document.cookie) // error 발생함
useEffect(() => {
console.log(document.cookie); // 클라이언트에서 렌더링 이후 이므로 값이 읽어짐 { token : 'JWT Token' }
}, []);
//...생략
document.cookie
는 클라이언트에서 읽어들일 수 있으므로 useEffect
안에서 값을 읽어 들여 사용 할 수 있으므로,
로그인 이후,
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
const { cookies } = ctx.req;
console.log("🚀 ~ getServerSideProps ~ cookies:", cookies);
return { props: { cookie: cookies } };
};
const Cookie = ({ cookie }: { cookie: { [key: string]: string } }) => {
console.log(cookie); // { token : 'JWT Token' }
//...생략
}
cookie에 있는 값을 header에 삽입 후 서버측에서도 http 통신을 하게 설정하면 된다.
cookie와 전역상태로 관리, 통신하면 되겠다는 생각이 있었지만, 무언가 찜찜한 기분이 들었다.
찜찜한 기분은 아마 react-query
또는 전역상태관리를 하나의 라이브러리?로만 해서 일것이다.
이런 찜찜한 기분을 자아 성찰?ㅋㅋㅋㅋ 하고, 되짚어 본 결과 3가지의 이유가 나왔다.
- 토큰 값 관리를
zustand
와cookie
두 군데에서 관리되는 것이 통일 되지 않는다.
클라이언트와 서버 간의 인증상태 불일치- 로그 아웃, 또는 토큰 갱신 할 때 각각의 로직을 2군대(zustand, cookie)에서 구현해야 하며, 일관된 로그아웃과 토큰 갱신을 보장하기 장담하지 못한다. 뿐만아니라, 일관된 코드를 구현 하기에 다소 DX적으로 auth라는 상위에 포함 되기 보단 auth와 cookie 두 군데라는 점이 낙관적이지 않다. 복잡한 상태관리
- 현재 공모전 프로젝트는 프로토타입이라 credential을 사용하여 인증/인가를 하지만, 그 이후 OAuth제공과 로직은 OAuth에서 지원받기 어려울 수 있다. 확장성 부족
이 3가지를 통해서 그렇다면 어떻게 auth를 관리하고, 처리 할 것인지 고민하였다. ( 하루 정도 고민 했던 것 같다 )
zustand와 쿠키를 사용하여 인증/인가 관리는 단순한 경우에 간단하지만, 통합되지 않은 인증관리와 세션관리의 일관성이 부족하다 판단하였다.
next-auth는 반대로
- 통합된 인증관리,
- 간편한 OAuth 접근과 설정,
- 세션관리의 일관성,
- 심지어 CSRF보호와 같은 보안성 향상을 통해
개발자가 직접 토큰을 관리하는 것 보다,
next-auth server로부터 인증/인가를 통해 관리 받게 하여, util함수, 훅을 통해 토큰에 접근하게 할 수 있다.
전역관리+cookie를 통해 토큰관리를 하지 않는 이유와 next-auth를 우리 프로젝트에서 사용해야 할 이유를 포스팅 해봤다.
다음 포스팅에선 next-auth의 사용법을 통해 우리 프로젝트에 적용시켜보자