RefreshToken

SongNoin·2021년 10월 24일
0
post-thumbnail

RefreshToken

  • 앞서 배운 AccessToken으로 로그인 데이터를 담아서 로그인 여부를 판단할 수 있었다.
    하지만 대부분의 사이트에서 보안등의 이유로 인해 만료시간을 정해둔다.
    만료시간이 지나고 AccessToken이 만료됐을 때 새로운 AccessToken을 받아오는 과정을
    RefreshToken이라고 한다!

  • 만약 AccessToken의 만료 시간이 1시간이라고 했을때 이용자는 1시간마다 새로 로그인을 해야한다. 그렇다면 매우 불편하고 다시 찾고싶지 않은 웹사이트가 될 수 도 있다.
    이를 위해 AccessToken을 발급할때 RefreshToken도 같이 발급하게 해준다.

  • 그렇다면 AccessToken이 만료된다 하더라도 RefreshToken이 이용자 몰래 로그인 과정없이 새로운 AccessToken을 받아내서 이용자에게 자연스러운 웹사이트 이용을 제공할 수 있다.

  • 하지만 RefreshToken에도 만료기간이 있기 때문에 RefreshToken이 만료된다면 다시 로그인을 진행시키도록 해야한다.

RefreshToken 적용시켜 보기

_app.js

  useEffect(() => {
    // const accessToken = localStorage.getItem("accessToken") || "";
    // setAccessToken(accessToken); // 이 두줄은 로컬스토리지에 저장하는 방법
    if (localStorage.getItem("refreshToken")) getAccessToken(setAccessToken);
  }, []);
// 만약 로컬 스토리지에 refreshToken가 true 값으로 존재할 경우 AccessToken을 받아온다.
  const errorLink = onError(({ graphQLErrors, operation, forward }) => {
    // @apollo/client의 onError의 기능을 사용한다.
    if (graphQLErrors) {
      for (const err of graphQLErrors) {
        if (err.extensions?.code === "UNAUTHENTICATED") {
          operation.setContext({
            headers: {
              ...operation.getContext().headers,
              authorization: `Bearer ${getAccessToken(setAccessToken)}`,
            },
          });
          return forward(operation);
        }
      }
    }
  });
  const client = new ApolloClient({
    link: ApolloLink.from([errorLink, uploadLink]), // 순서가 중요!
    cache: new InMemoryCache(),
  });

login.tsx

...
export default function LoginPage() {
  ...
    async function onClickLogin() {
    const result = await loginUser({
      variables: {
        email: myEmail,
        password: myPassword,
      },
    });
    localStorage.setItem("refreshToken", "true"); 
    // LocalStorage에 refreshToken을 true값으로 저장해준다.
    setAccessToken(result.data?.loginUserExample.accessToken);
    router.push("/32-02-login-success");
  }
  ...
  return (
    <>
      이메일 : <input type="text" onChange={onChangeEmail} />
      <br />
      비밀번호 : <input type="password" onChange={onChangePassword} />
      <br />
      <button onClick={onClickLogin}>로그인하기</button>
    </>
  );
}

0개의 댓글