로그인 유지를 어떤 방식으로 해줄 것인가?에 대하여 고민이 많았다.
로그인된 유저의 정보를 헤더 컴포넌트에 띄워 페이지 이동 시에도 로그인 상태를 유지하려고 했다.
그러기 위해 일단 리턴값으로 온 토큰을 쿠키에 저장하여 사용할 수 있도록 했다. (react cookies 라이브러리를 사용했다.)
const response = await axios.get(`/oauth/token?code=${code}`, {
withCredentials: true,
});
const { accessToken } = response.data;
cookie.save("accessToken", accessToken, {
path: "/",
});
dispatch(setToken(accessToken));
헤더 컴포넌트에서는 쿠키에 저장된 토큰을 헤더에 담아보내면서 로그인 정보를 요청했고 리덕스에 저장한 후 컴포넌트에서 사용하려고 해봤다.
그런데 수많은 undefined를 만났다.
리덕스를 사용하여 유저 정보를 저장했기에 리덕스에서 정보를 불러와 컴포넌트에 띄우려고 했다. 보여지기는 했지만 새로고침을 해도 유지가 안됐다. .,,
안해본 방법이 없었다. 미들웨어를 설치해보기도 하고 10버전 이상에서는 사용을 권장하지 않는 getInitialProps
를 사용해보기도 했다. 하지만 우리는 클라이언트 단에서 바로 통신을 주고받고 있고 프엔 서버인 api폴더에서 통신을 하고 있는 것이 아니기 때문에 당연히 로직은 적용되지 않고 새로고침하면 헤더의 상태가 풀렸다.
뭔가를 놓치고 있는 게 분명히 있어서 로그인이 아닌 다른 데이터들을 가져올 때 사용하는 로직을 살펴봤다.
설마 하면서 useState를 사용하여 user의 상태를 관리하고 저장하는 로직을 추가하고 받아온 로그인 정보를 setUser에 담았다.
user에 담긴 닉네임이 존재할 때 헤더에 띄우는 로직을 추가했는데 새로고침을 해도 유지가 되었다. 거의 일주일이 넘는 삽질 끝에 해결을 했다.
이게 완벽한 정답은 아닌 것 같지만 가장 기본적인 방법을 시도도 안해보다니..ㅠㅜ 허탈했다.
유저가 있다면 이미지, 닉네임과 로그아웃 버튼을 보여주고 유저가 없다면 로그인 버튼을 보여주도록 작성했다.
const [user, setUser] = useState<User[]>([]);
// setUser에 로그인 정보 담고,
// 닉네임과 이미지 꺼내서 헤더에서 보여주기
{!user ? (
<>
<button
id="login-btn"
className={styles["login-btn"]}
onClick={handleOpenLoginModal}
>
로그인
</button>
</>
) : (
<>
<Image
className={styles["kakao-profile-img"]}
src={user.imgUrl}
alt="카카오프로필"
width={45}
height={45}
/>
반가워요, {user.nickName} 님!
<button
id="login-btn"
className={styles["login-btn"]}
onClick={handleLogout}
>
로그아웃
</button>
</>
)}
function useDeleteToken() {
const dispatch = useDispatch();
useEffect(() => {
const deleteToken = () => {
cookie.remove("accessToken", { path: "/" });
dispatch(resetToken());
};
const timer = setTimeout(deleteToken, 1 * 60 * 1000); // 임의로 시간을 1분으로 설정했다.
return () => {
clearTimeout(timer);
};
}, []);
}
// next.config.js
const nextConfig = {
async rewrites() {
return [
{
source: "/:path*",
destination: "http://localhost:8080/:path*",
},
];
},
};
module.exports = nextConfig;