JWT 인증 구현

Kyung·2023년 5월 2일
0

설계

설계

accessToken과 refreshToken

  • accessToken: 지역 변수에 저장한다.
    • 어디서든 접근할 수 있도록 전역 상태로 관리함.
    • 요청에 직접적인 값으로 사용되므로 갱신 기간을 짧게 설정한다.
  • refreshToken: httpOnly 쿠키에 저장한다.
    • accessToken 갱신에만 사용되므로 갱신 기간을 적당히 길게 설정한다.

1. Login Flow

  • 유저가 아이디 비밀번호를 입력하고 로그인 요청을 보내면 서버는 응답으로 accessToken과 refreshToken을 내어준다.
    • accessToken => httpOnly cookie로
    • refreshToken => 응답값으로
  • accessToken과 refreshToken은 로그인 마다 생성된다.
  • accessToken은 유저를 구별할 수 있는 최소한의 정보를 암호화한다.
  • refreshToken은 accessToken이 만료되었을 경우, 재발급받을 수 있도록 하기 위해 생성 시, 데이터베이스에 저장한다.
    • client와 server 모두 쥐고 있게 된다.
  • 로컬 스토리지에 isAuth 값을 true로 바꾼다.
    • 로그인 후, 유저가 로그아웃 하지않은 상태에서 로그인 페이지로 이동하는 행위를 막기 위한 방법
    • 페이지 새로고침이 일어나면 지역 변수에 저장된 accessToken은 사라지고, refreshToken은 httpOnly 속성의 쿠키에 저장하여 클라이언트에서 접근하지 못하므로, 로그인 여부를 임의의 값으로 만들어 관리해야 했다.

2. Authenticated Endpoint

  • 인증이 필요한 엔드포인트의 경우에 요청 시, 요청 인터셉터(Request Interceptor)에서 헤더에 지역 변수로 가지고 있는 accessToken을 넣어준다.
  • 만약 요청의 응답로 401(accessToken expired) 에러가 떨어지면, 응답 인터셉터(Response Interceptor)에서 accessToken을 재발급받는다.
  • 만약 refreshToken이 만료되어 accessToken을 재발급 받을 수 없는 상황이라면 로그인 페이지로 이동한다.

3. Enter Login Page

  • 이전 설명에서 유저 로그인 상태를 관리하기 위해 로컬스토리지에서 isAuth라는 값을 관리한다고 했는데, 로그인한 상태에서 LoginPage로 이동하면 메인 페이지로 이동시킨다.
  if (isAuth) {
    return <Navigate to="/" />;
  }

4. Enter Authenticated Page

  • 인증이 필요한 페이지에 접근하면, 유효한 accessToken 인지 검증한다.
    • 만약 accessToken이 null이라면, refreshToken을 이용해 accessToken을 재발행한다.
    • accessToken이 지역 변수에 저장되므로, 페이지를 새로고침하면 accessToken은 휘발되므로 refreshToken을 이용하여 새로 발급받아야 한다.
    • 만약 accessToken을 재발행할 수 없다면(refreshToken이 없거나, 만료되었을 경우) 로컬스토리지의 isAuth 값을 false(null)로 바꾼 후, 로그인 페이지로 이동시킨다.
  • 인증이 필요한 페이지에서 무조건 accessToken을 검사하기 때문에, 로컬스토리지의 isAuth 값 조작으로 인한 해킹에 대해 걱정하지 않아도 된다.
  • 아래 코드는 인증이 필요한 페이지에 Wrapping된 HOC 컴포넌트
import useAuth from '../hooks/useAuth';

type AuthenticationProps = {
  children: React.ReactNode;
};

const Authentication = ({ children }: AuthenticationProps) => {
  const { isAuthenticated } = useAuth();

  if (!isAuthenticated) return null;

  return <>{children}</>;
};

export default Authentication;

5. Logout Flow

  • 클라이언트에서 가지고 있던 accessToken 값을 없애고, 로컬 스토리지에 저장하였던 isAuth 값을 false(null)로 바꾼다
  • refreshToken이 저장된 쿠키를 없앤다.
profile
개발 일지를 작성합니다

0개의 댓글