프로젝트

유저정보 저장하기 (오류해결 with redux-persist)

Jenner 2023. 2. 10. 17:06

 유저정보를 저장해야하는 이유 

 

유저가 로그인 하였을 때 유저정보 없이

로그인한 상태를 어떻게 구분할 수 있을까?

 

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로 저장하였다. 

context api vs 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를 사용하였다. 

자세한 사용방법은 다음 글에서 정리 해야겠다.