React | JWT 안전하게 저장하기 (localStorage 사용 X) (3)
지난글까지 완료한 상태라면, 다른 탭에서 로그아웃을 하더라도 모든 탭이 동시에 로그아웃이 되지만..
다른 탭을 생성하면 또 로그인을 해야한다. 이번 글에서는 이 문제를 해결한다!
Refresh Token을 Cookie에 저장!
최초 로그인 시 함께 발급되는 refresh_token
을 쿠키에 저장한다.
우선, 리액트에서 쿠키를 편하게 사용하려면 다른 라이브러리를 추가해야 한다.
아니면 documtn.cookie
로 생성하고, 삭제하고 해야 하는데 굉장히 번거로운 작업이다.. 물론 직접 해도 된다.
universal-cookie
를 사용할 것이다. react-cookie
를 사용해도 되긴 하지만, 자바스크립트 내에서만 사용할 것이므로..
npm install universal-cookie
auth.js 수정
우선 universal-cookie
를 import해주고, 생성자를 이용해 쿠키사용을 위한 선언을 한다.
import Cookies from 'universal-cookie';
const cookies = new Cookies();
쿠키는 key, value의 쌍 형식으로 저장되기 때문에 cookies.set()
메서드도 동일하게 키와 값, 그리고 옵션을 설정해 저장한다.
옵션에는 sameSite
설정을 추가해주었다.
export function setRefreshTokenToCookie(refresh_token) {
cookies.set('refresh_token', refresh_token, { sameSite: 'strict' });
}
그리고 로그아웃 하면 cookie도 삭제한다.
export function logout() {
console.log('localStorage set logout!');
window.localStorage.setItem('logout', Date.now());
cookies.remove('refresh_token');
}
App.js 수정
로그인에 성공하면, 발급받은 refresh_token
을 cookie
에 저장한다!handleLogin()
메서드를 수정한다.
function handleLogin(id, password) {
let token = auth.login(id, password);
if (token) {
console.log('로그인 성공!');
dispatch({
type: 'SET_TOKEN',
token: token,
result: true,
});
auth.setRefreshTokenToCookie(token.refresh_token); // cookie에 refresh_token 저장
} else {
console.log('로그인 실패');
dispatch({
type: 'SET_TOKEN',
token: null,
result: false,
});
}
}
이제 로그인에 성공하면 쿠키에 refresh_token
이 저장된다.refresh_token
은 access_token
이 만료되었을 경우에 access_token
을 발급받기 위한 토큰이다.
Refresh Token으로 로그인 유지하기
쿠키에 저장된 refresh_token
값으로 access_token
을 발급받고, 로그인을 유지시킨다.
auth.js 수정
getAccessToken()
이라는 메서드를 만들었다.
쿠키에 저장된 리프레시 토큰을 꺼내서 (원래는 리프레시 토큰이 유효한지도 확인해야 함) 새로운 토큰을 발급하도록..
export function getAccessToken() {
const refresh_token = cookies.get('refresh_token');
if (refresh_token) {
return {
access_token: 'dj7H8Jduyf,bw&%dkhdkszd',
refresh_token: 'djKJ/dio2jk*4KJHydhen,wlLlmddjk',
};
} else {
return undefined;
}
}
App.js 수정
useEffect()
를 통해 새로운 탭이 열렸거나, 인증 여부가 달라질 경우 refresh_token
으로 새롭게 access_token
을 발급받는다.
useEffect(() => {
const token = auth.getAccessToken();
if (token) {
dispatch({
type: 'SET_TOKEN',
token: token,
result: true,
});
auth.setRefreshTokenToCookie(token.refresh_token);
} else {
dispatch({
type: 'DELETE_TOKEN',
});
}
}, [authenticated]);
코드는.. 일단 JWT를 localStorage에 저장하지 않는 방법에 대해 이해한 것에 의의를 둔다...!!