유저정보 저장하기 (오류해결 with redux-persist)
● 유저정보를 저장해야하는 이유
유저가 로그인 하였을 때 유저정보 없이
로그인한 상태를 어떻게 구분할 수 있을까?
1. access token이 있으면 유저가 로그인했다고 할 수 있는가?
유효하지 않은 access token도 access token이 존재한다고 할 수 있다.
2. refresh token이 있으면 유저가 로그인했다고 할 수 있는가?
예.
그러나 refresh token은 앞선 글에서 cookies에 저장한다고 하였다.
cookie를 가져오는 함수로 유저가 로그인한 여부를 사용한다면
가독성이 떨어질 것이며,
유저의 정보를 사용하는데 한계가 있을 수 있다
-> decode과정에서 또다른 라이브러리 사용으로 무거워지지 않을까?
refresh token을 저장하려면 어차피 decode하여야 한다.
refresh token은 유효시간이 있으므로 해당 유효시간이 지나면 cookie에서 삭제되어야 할 것이기 때문에
decode가 필요한 것이다.
정리하자면
가독성과 유저 정보등의 이유에 의해 유저 정보를 저장하면 좋을 것이라고 생각이 된다.
●어디에 유저정보를 저장할 것인가?
유저정보는 많은 컴포넌트가 알아야 하기 때문에
전역적 상태로 관리되는 것이 좋을 것 같다고 생각이 들었다.
그래서 전역적 상태 관리인 redux로 유저정보를 저장하였다.
context api를 사용해도 될것같지만 일단은 redux로 저장하였다.
● 유저정보 저장하기
login.jsx중 userSetting함수
const userSetting = (authKey, refreshKey) => {
//localStorage.setItem("authKey", authKey);
//로컬스토리지에 저장하는 방식은 보안상 취약하므로 아래의 방식으로 변경
dispatch(authActions.login(authKey)); //store/auth에 access token을 저장
//token을 decode
const decoded = jwt(authKey);
//token에서 온 user정보를 저장
dispatch(authActions.user(decoded));
//refresh token을 cookie에 저장
cookies.set("jwt_authorization", refreshKey, {
expires: new Date(decoded.exp * 1000), //파기될때 삭제
httpOnly: true,
});
//로그인 완료 후 홈페이지로 돌리기
navigate("/home");
};
login.jsx중 submitHandler함수
//로그인 버튼 클릭시, api통신
const submitHandler = (e) => {
e.preventDefault();
console.log("submit clicked");
console.log(idState.value, pwState.value);
//login시 필요한 data형식이 formData이므로 형식에 맞게 만들어주기
const formData = new FormData();
formData.append("username", `${idState.value}`);
formData.append("password", `${pwState.value}`);
fetch("http://localhost:8000/login/", {
method: "POST",
body: formData,
})
.then((res) => {
if (!res.ok) {
throw new Error(`Error accured! The status is ${res.status}`);
} else {
return res.json();
}
})
.then((data) => {
console.log(data);
userSetting(data.Authorization, data.RefreshToken);
})
.catch((error) => {
console.error(error.message);
});
};
● 유저정보 활용방식
const user = useSelector((state) => state.auth.user);
return (
<>
{user && <MyList/>}
</>
)
useSelector로 user의 상태를 가져와서,
user가 있다면 MyList와 같은 보호된 리소스를 렌더링해준다.
● 오류 : 새로고침을 누르면 로그인이 풀려버린다.
redux는 전역적 state 관리 시스템이지만,
당연하게도 새로고침하면 브라우저에 상태가 남아있지 않는다.
브라우저에는 아무런 state도 저장되어있지 않기 때문이다.
이 상태를 유지하기 위해 redux-persist를 사용하였다.
자세한 사용방법은 다음 글에서 정리 해야겠다.