요새 시대에 로그인을 직접구현하는 사이트는 거의 없다.
왠만하면, OAuth로 구글, 카카오, 네이버 등을 사용한다.
본 프로젝트에서는 Github OAuth로 연동하여 사용하기 때문에, 링크 자체는 Github로 설명하겠다.
또한, 프론트엔드만의 입장이기 때문에 백엔드 구현에 있어서는 Github문서 구글문서들을 참조하기 바란다.
OAuth를 이해하기 위해선 과정을 알아야한다. 다음의 과정으로 인증과정을 거친다.

로그인링크는 /oauth/github 같은 백엔드 API이다. 해당 백엔드 API에 요청을하면 Github 사이트로 리다이렉트가 되는 것이다.
그렇다면 리액트에서 만들어야할 것은 무엇일까?
바로 로그인 후 이동할 callback 페이지를 만드는 것이다.
callback 페이지에서 액세스토큰, 리프레시토큰을 전달받고 로그인 후 이동할 페이지로 새로 이동시키는 기능을 구현해야한다.
즉, callback 페이지는 디자인구현이 있는 것이 아니라, 단순 useEffect훅으로 기능실행만 돌아가면 된다는 것을 의미한다.
function requestGithubLogin() {
window.location.href =
"http://서버IP:8080/oauth2/authorization/github?redirect_uri=http://localhost:3000/callback";
}
위 함수는 리액트에서 로그인버튼의 onClick 이다.
버튼을 클릭하면 github 로그인 페이지가 열리며, 로그인 성공시 프론트엔드의 /callback 라우터로 이동시켜줌을 의미한다.
물론 쿼리파라미터에 액세스토큰과 리프레시토큰도 함께 전달해준다.
import { useEffect } from "react";
function Callback() {
useEffect(() => {
const handleOAuthCallback = async () => {
const params = new URLSearchParams(window.location.search);
const accessToken = params.get("access_token");
const refreshToken = params.get("refresh_token");
if (accessToken) {
var currentDate = new Date();
var accessExpirationTime = new Date(currentDate.getTime() + 15 * 60000);
document.cookie = `studitAccessToken=${accessToken}; expires=${accessExpirationTime.toUTCString()}; path=/`;
}
if (refreshToken) {
currentDate = new Date();
var refreshExpirationTime = new Date(
currentDate.getTime() + 7 * 24 * 60 * 60000,
);
document.cookie = `studitRefreshToken=${refreshToken}; expires=${refreshExpirationTime.toUTCString()}; path=/`;
}
window.location.href = "http://localhost:3000/home";
};
handleOAuthCallback();
}, []);
return null;
}
export default Callback;
이동한 callback 페이지에선 위와 코드를 실행해야한다.
현재 url에서 액세스토큰, 리프레시토큰을 가져온다.
localStorage 혹은 sessionStrorage, 쿠키 등 기능명세에 정해진 대로 토큰을 저장한다.
여기서는 쿠키를 사용하기 때문에, API와 맞춰 만료시간을 설정하고 저장한다.
이후 이동할 곳은 /home라우트이기 때문에 window.location.href로 이동시켜주었다.
Callback 페이지도 위의 flow 1번 과정에서의 callback url과 일치해야하기 때문에, App.js에서 라우터로 다음과 같이 등록을 해주어야한다.
<Routes>
<Route path="/callback" element={<Callback />} />
<Route path="/" element={<Splash />} />
<Route element={<PrivateRoute authentication={true} />}>
<Route path="/home" element={<Home />} />
<Route path="/calendar" element={<Calendar />} />
<Route path="/mystudies" element={<Mystudies />} />
<Route path="/settings" element={<Settings />} />
</Route>
</Routes>
매우 간단하다. 토큰을 쿠키에 저장했으므로 쿠키를 비우면 된다.
쿠키를 삭제하는 대표적인 방법은 쿠키의 만료일을 1970년 1월 1일(개발자 그 국룰시간 ㅋㅋ)로 설정하는 것이다.
function logout() {
document.cookie =
"studitAccessToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
document.cookie =
"studitRefreshToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
window.location.href = "/";
}
위는 쿠키를 삭제시키고 새로고침하는 코드이다.
새로고침을 한 이유는 유효한 토큰을 가지고 있을 때는 sign out 버튼을,
유효하지 않은 토큰을 가지거나(만료된 토큰) 토큰이 없을땐 sign in 버튼을 사용자에게 보여주기 위해
useEffect 훅으로 감지하는데 이를 갱신하기위해 새로고침하는 것이다.