42gg 프로젝트에서 로그인 페이지를 담당하게 되었다.
Oauth를 사용하여 로그인을 구현하기로 했다.
42gg는 42서울 카뎃들만 사용할 수 있는 사이트이다. 하여 42API에서 제공하는 Oauth 인증을 통해 로그인 시스템을 구현하였다.
OAuth는 사용자가 누구인지를 확인하는 인증(Authentication) 프로토콜이 아닌, 사용자의 요청이 권한이 있는지를 확인하는 인가(Authorization) 프로토콜이다.
로그인 상태관리를 위해 Recoil을 사용한다. atom() 함수를 사용하여 상태 단위를 만들어주고, recoilPersist를 사용하여 페이지가 변경된 후에도 상태관리를 유지할 수 있도록 한다.
npm install recoil-persist
import { recoilPersist } from 'recoil-persist';
import { atom } from 'recoil';
import { v1 } from 'uuid';
const { persistAtom } = recoilPersist();
export const loginState = atom<boolean>({
key: `loginState/${v1()}`,
default: false,
effects_UNSTABLE: [persistAtom],
});
import하여 로그인 상태를 필요한 페이지에서 사용할 수 있다. atom을 통해 컴포넌트간 데이터를 공유할 수 있게 된다.
import { useRecoilState } from 'recoil';
import { LoginState } from 'States/LoginState';
const [isLoggedIn, setIsLoggedIn] = useRecoilState(LoginState);
사용자가 로그인을 하기 위해 인증페이지에서 권한을 승인해주면, url의 파라미터로 유저의 토큰이 담겨서 리다이렉트 된다. 해당 토큰을 받아서 local storage에 저장해준다. 로컬스토리지의 데이터는 만료되지 않고 계속하여 사용할 수 있다.
import { useRouter } from 'next/router';
const router = useRouter();
const token = router.asPath.split('?token=')[1];
useEffect(() => {
if (token) {
localStorage.setItem('42gg-token', token);
router.replace(`/`);
}
if (localStorage.getItem('42gg-token')) {
setIsLoggedIn(true);
}
}, []);
저장된 토큰은 서버에 데이터를 요청할 때 사용한다. 요청 메시지 헤더에 Authorization를 추가하여 key-value형태로 담아 서버로 보내주어 본인 임을 확인하게 해준다.
headers: {
'Content-Type': 'multipart/form-data',
Authorization: `Bearer ${localStorage.getItem('42gg-token')}`,
},
setRankData(res?.data);
const onLogout = () => {
localStorage.removeItem('42gg-token');
setIsLoggedIn(false);
router.push(`/`);
};
이 포스팅만 목록에서 빠져있어요!