[42gg] 로그인 구현하기

Daehyun·2022년 7월 19일
1

42gg

목록 보기
5/8
post-thumbnail

42gg 프로젝트에서 로그인 페이지를 담당하게 되었다.
Oauth를 사용하여 로그인을 구현하기로 했다.

42gg는 42서울 카뎃들만 사용할 수 있는 사이트이다. 하여 42API에서 제공하는 Oauth 인증을 통해 로그인 시스템을 구현하였다.


0.Oauth

OAuth는 사용자가 누구인지를 확인하는 인증(Authentication) 프로토콜이 아닌, 사용자의 요청이 권한이 있는지를 확인하는 인가(Authorization) 프로토콜이다.

  • oauth의 흐름을 보여주는 시퀀스 다이어그램이다.
  • 42의 정보를 42gg에서 사용하려면 유저에게서 권한 부여 승인을 받아야한다. 로그인 페이지에서 로그인을 누르면 인증페이지로 보내 권한 승인을 하도록 한다.
  • 권한이 승인되면 사용자에 대한 정보가 서버로 넘겨지며, 사용자 고유의 토큰을 받아온다. 해당 토큰을 저장하여 사용자 본인이 맞는지 확인하고 로그인 상태를 유지할 수 있다.

1. 로그인 상태 만들기

  • 로그인 상태관리를 위해 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);

2. 토큰 저장하기

  • 사용자가 로그인을 하기 위해 인증페이지에서 권한을 승인해주면, 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);

3. 로그아웃 하기

  • 로그아웃 버튼을 누르면 로그인 상태를 false로 바꾸고 저장된 token을 삭제하여 로그아웃 하도록 한다. 로그아웃 되면 메인페이지로 이동시켜주고, 로그인 페이지로 넘어가게 된다.
     const onLogout = () => {
       localStorage.removeItem('42gg-token');
       setIsLoggedIn(false);
       router.push(`/`);
     };

4. 고민해보기

  • token을 url로 받는 방법 말고는 없을까? 쿠키, 헤더 등에 담아오는 방법도 고민해보자.
  • access, refresh token의 두 종류의 토큰을 사용해야 하는데, 이 토큰은 백엔드 서버에서 관리하는 것이 맞을까? 프론트에서 42api와 주고받으면서 갱신해주어야 하지는 않을지 고민해보자.
  • 현재는 토큰을 localstorage에 저장을 하고 사용하지만, 이 부분도 고민해봐야할 부분이지 않을까 싶다.

5.참고자료

2개의 댓글

comment-user-thumbnail
2022년 7월 27일

이 포스팅만 목록에서 빠져있어요!

1개의 답글