웹에서 요청마다 매번 연결과 해제가 되면서 요청마다 새로운 사용자로 인식되는 단점이 있지만, 쿠키와 세션을 통해 브라우저를 종료했다가 다시 접속해도 로그인 상태를 유지할수있다.
쉽게말하면, 쿠키는 서버를 대신해 웹 브라우저에 저장하고 요청을할때 그정보를 서버에 보내 사용자를 식별할수있게 한다.
쿠키는 세션관리, 개인화, 트래킹에 사용되며, 세션은 쿠키를 이용한다. 웹브라우저가 서버에 요청을 하면 서버는 세션 아이디를 할당해서 응답할때 함께 전달한다.
쿠키는 서버가 사용자의 웹브라우저에 저장하며 데이터 형태는 Key, value형태로 String문이며, 4KB 이상 저장이 불가하다. 브라우저마다 저장되는 쿠키는 다르다.
클라이언트가 서버로 요청을 보낸뒤, 그에대한 지속 필요정보를 서버에서 쿠키에 담아 보낸다. 이에 클라이언트는 pc에 저장한 뒤 서버에 요청을 보낼 떄마다 쿠키를 같이 보낸다.그래서, 쿠키에 대한 정보를 매 통신 시 Header에 추가하여 보내기 때문에 상당한 트래픽을 발생시킨다. 결론으로는 쿠키는 클라이언트에 저장되어 보안이 취약하며, 클라이언트 pc에 저장되는것이기 때문에 브라우저를 종료해도 계속 남아있다.
서버가 클라이언트마다 개별의 세션 ID를 부여하고, 클라이언트는 요청할 때마다 세션 ID를 서버에 전달한다. 서버는 받은 세션 ID로 클라이언트 정보를 가져와 활용한다. 장점은 쿠키보다 보안성이 뛰어나다는 것이며, 단점으로는 쿠키에 비해 서버에서 부담하는 처리량이 늘어난다는것이다. 즉, 사용자가 많아지면 서버 측 부하가 늘어난다. 이러한 특징으로 속도도 쿠키보다 느리다. 또한 브라우저가 종료되면 삭제된다.
yarn add react-cookie
쿠키와 관련된 함수를 모아두는 util 파일을 만든다.
cookie.js
import {Cookies} from 'react-cookie'
const cookies = new Cookies()
export const setCookie = ()=>{
return cookies.set(name, value, {...options})
}
export const getCookie = ()=>{
return cookies.get(name)
}
set과 get함수로 쿠키를 저장하고 이용하면된다.
import {CookiesProvider} from 'react-cookie';
ReactDOM.render(
<CookiesProvider>
<App/>
</CookiesProvider>
document.getElementById('root')
)
로그인 함수가 있는곳에서 setCookie를 통해 jwt토큰을 저장한다.
const jwtToken = await signIn(signInPayload)
if(jwtToken){
setCookie('loginToken', token, {
path:"/",
secure:true,
sameSite:'none',
}
}
await axios({
method:'get',
url:'api',
headers:{
'Content-Type':'application/json',
Authorization : `Bearer ${getCookie('jwtToken')}`,
}
})
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { CookieProvider } from "react-cookie";
ReactDOM.render(
<CookieProvider>
<App />
</CookieProvider>,
document.getElementById("root")
);
App.js
import "./App.css";
import { useCookies } from "react-cookie";
import React, { useEffect, useState } from "react";
function App() {
const [text, setText] = useState("");
const [isRemember, setIsRemember] = useState(false);
const [cookies, setCookie, removeCookie] = useCookies(["rememberText"]);
//cookies는 쿠키의 정의,
//setCookie는 쿠키를 재정의,
//removeCookie는 쿠키 제거이다.
//useCookies 안에는 초기값을 넣는다.
let now = new Date();
let after1m = new Date();
useEffect(() => {
if (cookies.rememberText !== undefined) {
setText(cookies.rememberText);
setIsRemember(true);
}
});
function onChange(e) {
setText(e.target.value);
}
const handleOnChange = (e) => {
after1m.setMinutes(now.getMinutes() + 1); // after1m를 현재시간의 1분뒤로 정의
setIsRemember(e.target.checked);
if (e.target.checked) {
setCookie("remeberText", text, { path: "/", expires: after1m });
// remeberText에 text라는 값을 넣는다.
// path는 적용되는 도메인
// expires = 만료시간은 1분뒤
} else {
removeCookie("rememberText");
// checkBox의 체크를 지울시
// 쿠키 remeberText를 지운다
}
};
return (
<>
{" "}
<input value={text} onChange={onChange} />{" "}
<input type="checkBox" onChange={handleOnChange} checked={isRemember} />{" "}
<h1>{text}</h1>{" "}
</>
);
}
export default App;
setCookie 에서는 3가지 파라미터를 받는다.
path
는 쿠키의 값을 저장하는 서버경로이다. 기본적으로는 '/'이고, 모든페이지에서 쿠키에 접근할 수있다. /a인 경우 domain.com/a에서만 접근할수있다는것이다.
expires는 만료시간이며, Date객체를 받는다.
secure는 true인 경우에는 https로 통신할때만 쿠키가 저장된다.
httpOnly는 document.cookie와 같은 자바스크립트 코드로 쿠키에 비정상적인 접근하지 않도록 막는다.
함수를 통해 쿠키를 저장하고 불러올수도있다.
const expires = new Date()
expires.setMinutes(expires.getMinutes() + 60)
cookie.save('hello', 'test', {
path: '/'
expires,
//secure : true,
//httpOnly : true
});
setTimeout(()=>{
alert(cookie.load('aaa'))
},1000);
}
save함수를 통해 쿠키를 저장했다면 load함수를 통해 쿠키에 접근해 value를 가져올수있다. remove도있다.
최그에는 업그레이드 된 모듈인 universal-cookie 라는것도 있다. 다음 시간에 사용해보자.
yarn add universal-cookie