설계

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이 저장된 쿠키를 없앤다.