내가 나중에 보려고 정리한다. JWT 토큰을 이용한 Authentication. 개념과 로그인 구현을 위한 모든 것들을 프론트 위주에서 기록해보았다. 0 to 100. (해당 글은 미완성이며 추가하는 중입니당)
일단 JWT에 대해 알아보기 전에 session을 이용한 로그인 처리를 알고 있으면 좋은데 이 포스팅에서는 session에 대한 자세한 설명은 생략한다.
"이 두 토큰을 클라이언트에서 가지고 있다가" ... 오키. 그럼 클라이언트 어디에 저장하면 좋을까?
JWT 토큰의 저장 위치는 크게 웹 스토리지, 쿠키 두 곳으로 나뉜다.
웹 스토리지
웹 스토리지에는 LocalStorage와 SessionStorage가 있다. 서버에서는 접근할 수 없다는 특징을 갖는다. 스토리지에는 바로 접근이 가능하기 때문에 XSS에 취약하다.
쿠키
서버에서 접근할 수 있으며 HttpOnly 설정을 추가해서 XSS를 차단할 수 있다. Http Request 시 자동으로 포함된다.
결론적으로 웹 스토리지 방식은 구현이 더 쉽지만 보안 측면에서는 쿠키가 더 좋다.
우선은 토큰이 만료 되었을 때 연장하는 것은 제외하고 설명한다. (그럼 이 경우는 AccessToken만 필요하겠지만 RefreshToken 없이 말하면 어색해서 언급함)
그리고 토큰이 만료되었을 때 연장하는 절차는 아래와 같다.
나는 보안 측면에서 유리한 쿠키에 토큰을 저장하기로 했다. 그럼 우선 npm 패키지를 사용해서 리액트에서 쿠키에 get, set 하는 방법에 대해 언급하고자 한다.
react-cookie 라이브러리을 사용하면 리액트 코드에서 쿠키를 손쉽게 사용할 수 있다. 자세한 설명은 패키지 설명을 참고 바람.
import React, { useState, useEffect } from "react";
import { useHistory } from "react-router-dom"
import { useCookies } from 'react-cookie';
const SigninForm = () => {
const history = useHistory();
const [userId, setUserId] = useState("");
const [userPassword, setUserPassword] = useState("");
// 'rememberUser'라는 key를 갖는 쿠키 생성
const [cookies, setCookie, removeCookie] = useCookies(['rememberUser']);
useEffect(() => {
if(cookies.rememberUser !== undefined) {
setUserId(cookies.rememberUser);
}
}, [cookies.rememberUser]);
const handleSignin = (event) => {
if (로그인 성공하면) {
setCookie('rememberUser', userId, {path:'/', maxAge: 2000});
} else {
removeCookie('rememberUser');
}
history.go(0); // 새로고침
event.stopPropagation();
};
return (
<div>
// 생략
</div>
)
}
우선은 Hook을 이용해서 JWT 토큰이 아닌 아이디 자체를 저장하는 간단한 예제를 진행해봤다. 매우 간단한 예제라 코드만 보면 금방 이해가 될 것이다. setCookie
, removeCookie
등으로 쿠키를 쉽게 조작할 수 있다.
그리고 위 예제를 실행하고 개발자 모드를 켜서 확인하면 로그인 성공 시, 쿠키에 rememberUser라는 key로 쿠키가 세팅되는 것을 확인할 수 있다.
import React, { useEffect, useState } from "react";
import { Cookies } from "react-cookie";
const Navbar = () => {
const cookies = new Cookies();
// 생략
return (
<div>
<Link >
{cookies.get('rememberUser') ? "로그아웃" : "로그인"}
</Link>
</div>
);
};
그리고 다른 컴포넌트에서 쿠키에 get 하고자 하면 위처럼 한다. 쿠키 객체를 생성해주고 cookies.get()
으로 얻는다. 위 예제는 로그인이 되어 있으면 "로그아웃", 로그인이 안되어 있으면 "로그인" 이라고 나오게 하는 예제다.
이와 같은 방식으로 JWT 토큰을 저장하면 되는데, 그건 추후에 추가하겠음!