[TIL 0413] 브라우저에 accessToken 저장하기

zitto·2023년 4월 14일
0

TIL

목록 보기
46/77
post-thumbnail

accessToken을 변수에 넣어 두고 사용하는데,
왜 새로고침하면 사라질까?
로그인 정보가 모두 날아가서!

왜 날아가냐?
새로고침은 브라우저에서 해당 주소로 다시 enter를 친것과 같음!

주소창에 주소를 입력하는 순간
프론트엔드서버 컴퓨터에 접속해서
html,css,js를 다운받아가지고 온다.
그 다운받은걸 화면에 그려줌
등록하기버튼등 유즈쿼리 요청하면 백엔드접속해서 디비에서 가지고와서 보내주는 과정임.

따라서 새로고침을 하게 되면
새로운 html,css,js를 다운 받아서 다시 그려냄
전부 초기화됨!
이전에 그려주었던 state변수들이 날아가게 되기 때문에 accesToken이 날아갔던 것

그럼 accessToken은 어디에 저장해야 새로고침을 해도 날아가지 않을까?

정답은 바로 브라우저!

브라우저에는 저장할 수 있는 공간이 여러가지가 있으며, 우리는 이 공간들을 브라우저 저장소라고 한다.

로컬에 저장하는 것 보안문제가 있음!
일단 임시로만 저장하자


[실습]

  • login-localstorage.tsx
export default function LoginPage(): JSX.Element {
  const router = useRouter();
  const [, setAccessToken] = useRecoilState(accessTokenState);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [loginUser] = useMutation<
    Pick<IMutation, "loginUser">,
    IMutationLoginUserArgs
(LOGIN_USER);
  const onChangeEmail = (event: ChangeEvent<HTMLInputElement>): void => {
    setEmail(event.currentTarget.value);
  };
  const onChangePassword = (event: ChangeEvent<HTMLInputElement>): void => {
    setPassword(event.currentTarget.value);
  };
  const onClickLogin = async (): Promise<void> => {
    try {
      // 1. 로그인 뮤테이션 날려서 accessToken 받아오기
      const result = await loginUser({
        variables: { email, password },
      });
      const accessToken = result.data?.loginUser.accessToken;
      console.log(accessToken);
      // 2. 받아온 accessToken을 globalState에 저장하기
      if (accessToken === undefined) {
        alert("로그인에 실패했습니다! 다시 시도해 주세요!"); //백엔드에서 에러메시지 안주면 error.message뜸.
        return;
      }
      setAccessToken(accessToken);
      localStorage.setItem("accessToken", accessToken); //임시로 사용! 나중에 지울 것임
      // 3. 로그인 성공 페이지로 이동하기
      void router.push("/section23/23-01-login-success");
    } catch (error) {
      if (error instanceof Error) alert(error.message);
    }
  };
  return (
    <>
      이메일: <input type="text" onChange={onChangeEmail} />
      비밀번호: <input type="password" onChange={onChangePassword} />
      <button onClick={onClickLogin}>로그인</button>
    </>
  );
}
  • loin-localstorage-success.tsx
//API날려서 뿌려주는 작업 accessToken작업은 없음.
import { gql, useQuery } from "@apollo/client";
import type { IQuery } from "../../../src/commons/types/generated/types";
const FETCH_USER_LOGGED_IN = gql`
  query {
    fetchUserLoggedIn {
      email
      name
    }
  }
`;
export default function LoginPage(): JSX.Element {
  const { data } =
    useQuery<Pick<IQuery, "fetchUserLoggedIn">>(FETCH_USER_LOGGED_IN);
  return <>{data?.fetchUserLoggedIn.name}님 환영합니다!</>;
}

로그인 후 받아온 토큰을 브라우저에 저장해둘 수 있도록 localStorage.setItem(key,value) 을 이용해 브라우저에 accessToken을 저장한다.

그러나 실제로 accessToken이 저장되는 곳recoil의 recoilState의 accessToken이라는 변수에 저장되어있다.

새로고침을 하게되면 app전체가 제일 먼저 새로 그려지기 때문에 여전히 accessToken변수가 새로 그려지게 된다.

따라서 login페이지에서 브라우저에 저장해둔 accessToken을 getItem을 통해 가져와,
setAccessToken에 다시 넣어주어 브라우저 저장된 토큰으로 바꿔줘야 한다.

그런데 !!!!

localstorage is not defined 라는 에러가 뜬다.
이 부분은 next.js의 렌더링 방식때문에 발생하는 것!

next.js의 렌더링 방식 설명
https://velog.io/@zitto/TIL-0413-Next.js의-렌더링-방식


localStorage 사용방법

  • 저장할 때 : localstorage.setItem(”key” , ”value”)
  • 꺼내올 때 : localstorage.getItem(”key”)
profile
JUST DO WHATEVER

0개의 댓글