[42byte] Recoil로 로그인 상태 관리하기

tamagoyakii·2022년 3월 28일
8

42byte

목록 보기
3/3
post-thumbnail

42byte는 42서울 학생들만 이용할 수 있는 커뮤니티다. 따라서 OAuth 프로토콜을 이용한 Access Token이 필요하다. 서버에서 url에 담아서 보내준 Access Token으로 로그인을 정보를 관리하는 방법에 대해 써보려고 한다.

1. 로그인 state 만들기

RecoilState를 사용하여 로그인 상태를 관리한다. States 폴더 안에 LoginState.ts 파일을 만들어준 다음 아래의 코드를 넣어주었다.

import { atom } from 'recoil';
import { recoilPersist } from 'recoil-persist';

const { persistAtom } = recoilPersist();

export const LoginState = atom<boolean>({
  key: 'LoginState',
  default: false,
  effects_UNSTABLE: [persistAtom],
});

여기서 LoginStateAtoms라고 부르는데, 이것은 상태의 단위이다. Atoms는 React의 로컬 컴포넌트의 상태 대신 사용할 수 있으며,atom()함수를 사용해 생성된다. recoilPersist는 페이지가 변경되더라도 상태관리를 유지하기 위해 사용된다. 만들어준 로그인 상태를 페이지에서 사용하고 싶을 때는 아래와 같이 import 하면 된다.

import { useRecoilState } from 'recoil';
import { LoginState } from 'States/LoginState';

const [isLoggedIn, setIsLoggedIn] = useRecoilState(LoginState);

useRecoilStateatom을 읽고 쓰려고 할 때 사용하는 Hook이다. ReactuseState와 비슷하지만 상태가 컴포넌트 간에 공유될 수 있다는 차이가 있다. 로그인 상태를 담아줄 변수를 만들었다면 다음은 토큰을 저장하고 로그인 상태를 변환해주는 단계로 넘어간다.

2. 토큰 저장하기

OAuth 프로토콜 이후 유저들은 42byte의 메인 페이지로 리다이렉트 된다. 이때 서버는 url주소에 토큰을 넣어서 보내주는데, 클라이언트는 url에 담겨있는 토큰을 로컬스토리지(Local Storage) 에 담아서 사용하기로 했다. 로컬스토리지에 저장한 데이터는 브라우저 세션 간에 공유된다. 이는 세션스토리지(Session Storage) 와 비슷하지만, 세션스토리지의 데이터는 페이지 세션이 끝날 때, 즉 페이지를 닫을 때 사라지지만, 로컬스토리지의 데이터는 만료되지 않는다. 아래와 같이 url의 token 부분을 잘라서 저장해준다.(토큰은 노출되면 안되기 때문에 토큰을 저장한 뒤 토큰이 보이지 않도록 처리하는 코드를 나중에 추가했다.)

const token = window.location.href.split('?token=')[1];

그 다음 useEffect를 사용해 로컬스토리지에 토큰을 저장해주고, 저장에 성공했다면 로그인 상태를 true로 만들어준다.

useEffect(() => {
  if (token) localStorage.setItem('4242-token', token);
  if (localStorage.getItem('4242-token')) setIsLoggedIn(true);
}, []);

여기서 로컬스토리지의 두 가지 메서드를 사용했다.

setItem(key, value) : 키-값 쌍을 보관한다.
getItem(key) : 키에 해당하는 값을 받아온다.

42byte 토큰의 키는 '4242-token', 값은 위에서 저장한 토큰이다. 키 이름은 사이트 이름을 정하기 전에 만들어서 뭔가 직관적이지 못한데, 수정이 필요할 것 같다. 위 과정이 끝났다면, 어디서든 useResoilState를 사용해 로그인 상태를 관리할 수 있다.

3. 로그아웃

로그인 과정이 끝났다면, 마지막으로 로그아웃에 대한 처리가 필요하다. 42byte의 로그아웃 버튼은 메뉴바에 있기 때문에 메뉴바에 아래와 같은 코드를 추가해줬다.

import { useRecoilState } from 'recoil';
import { LoginState } from 'States/LoginState';

const [isLoggedIn, setIsLoggedIn] = useRecoilState(LoginState);

const logoutHandler = () => {
  localStorage.removeItem('4242-token');
  setIsLoggedIn(false);
  window.location.href = '/';
};

logoutHandler는 로그아웃 버튼을 눌렀을 때 실행되는 함수다. 여기서 로컬스토리지의 removeItem 메서드를 사용하는데, 이는 이름에서 알 수 있듯이 키와 해당 값을 삭제하는 메서드이다. 로그아웃 버튼을 누르면 로컬스토리지에 있는 '4242-token'이 삭제되고, 로그인 상태가 false값이 된다. 이후 메인페이지로 보내지면서 로그아웃 처리가 완료된다.

4. 참고

https://recoiljs.org/ko/docs/api-reference/core/atom
https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage

0개의 댓글