[리액트] 카카오 소셜 로그인

임승민·2022년 9월 6일
1

위엔비 프로젝트

목록 보기
3/5
post-thumbnail

💡 카카오 소셜 로그인 flow

  1. FE 측에서 카카오에게 인가 코드를 요청한다.
  2. 받은 인가 코드를 서버에 보낸다.
  3. 서버는 인가코드로 카카오에게 토큰을 요청한다.
  4. 유효한 코드면 토큰을 발급해 준다.
  5. 카카오 토큰으로 유저정보를 확인하고 이를 통해 서버 전용 토큰을 발행한다.
  6. 서버 전용 토큰을 FE에게 보낸다.

인가코드 요청

인가코드를 요청하려면 kakao developers에서 REST_ API와 Redirect URI를 먼저 얻어야 한다.

API_KEY와 같이 노출 되면 보안 위협이 될 수 있는 정보들은 .env파일을 통해 환경변수로 설정해 관리하는 것이 좋다. 또한 gitignore에 .env 파일을 등록해 github상에 노출되지 않도록 해야한다. 그렇기 때문에 팀원들 끼리 공유를 통해 설정한다.

리액트의 경우 변수 앞에 REACT_APP_을 꼭 붙여줘야 한다.
또한 값을 따옴표로 감싸면 스트링으로 인식해 정상적으로 동작하지 않을 수 있어 따옴표는 사용하지 않는다.

// .env
REACT_APP_API_KEY = 비밀
REACT_APP_REDIRECT_URI = http://localhost:3000/kakao

주소를 변수에 할당하는데 이때 그냥 REST_API_KEY와 같이 사용하면 동작하지 않는다.

.env 파일의 경우 앞에 process.env.를 붙여 줘야 사용할 수 있다.

LoginKakaoWrap이라는 링크를 클릭하면 해당 URL로 이동한다.

// Login.js
const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=${process.env.REACT_APP_API_KEY}&redirect_uri=${process.env.REACT_APP_REDIRECT_URI}`;
---
<LoginKakakoWrap href={KAKAO_AUTH_URL}>

URL로 이동하면 카카오 동의서가 나온다. 모든 절차를 통과하면 URI 뒤에 인가코드가 담겨있는 페이지로 이동한다.

http://localhost:3000/kakao?code=인가코드

서버로 인가코드 전송, 토큰 수령

그럼 인가코드를 어떻게 가져올 수 있을까

우선 라우터에 해당 경로를 등록하고 컴포넌트를 연결한다.

// router.js
<Route path="/kakao" element={<KakaoLoding />} />

인가코드 페이지에 접속했을 때 이용될 KakoLoding이란 컴포넌트를 만든다.

로그인이 성공 했을 때 서버로 인가코드를 보내기 위해선 인가코드를 받은 화면의 시점에서 fetch를 보내야 한다.

// KakoLoding.js
const KakaoLoding = () => {
  let code = new URL(window.location.href).searchParams.get('code');
  const navigate = useNavigate();

  useEffect(() => {
    const goToMain = () => {
      navigate('/');
    };
    fetch(`http://10.58.4.138:3000/kakao/auth?code=${code}`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    })
      .then(response => response.json())
      .then(data => {
        if (data.message === 'success') {
          localStorage.setItem('TOKEN', data.token);
          goToMain();
          alert('로그인 성공');
        } else {
          goToMain();
          alert('로그인 실패');
        }
      });
  }, [code, navigate]);
};
  1. new URL(window.location.href).searchParams.get('code') 을 통해서 code= 뒤의 인가코드를 code라는 변수에 담아준다.
  2. useEffect를 사용해 해당 페이지가 렌더링 될때 URL의 파라미터로 code를 담아 해당 주소로 전송한다.
  3. 전송 후 받은 객체의 message가 success면 localStorage에 ‘TOKEN’이란 키에 서버로 부터 받은 토큰을 값으로 할당한다.
  4. 그리고 goToMain함수를 통해 메인 화면으로 보내고 로그인 성공을 안내한다.
  5. 만약 실패했다면 메인으로 보내고 로그인 실패를 안내한다.

로그아웃

로그인 혹은 회원가입에 성공 했다면 이제 로그아웃을 할 차례이다.

메인페이지에 logoutHandle이라는 함수를 만들어 줬다.

const logoutHandle = () => {
    fetch(`http://IP:3000/kakao/logout`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        authorization: localStorage.getItem('TOKEN'),
      },
    })
      .then(response => response.json())
      .then(data => {
        if (data.message === 'success') {
          localStorage.removeItem('TOKEN');
          alert('로그아웃 성공');
        } else {
          alert('로그아웃 실패');
        }
      });
  };
  1. 로그아웃 버튼을 클릭하면 해당 함수가 실행된다.
  2. 서버로 로그아웃할 해당 token을 보낸다.
  3. 정상적으로 삭제가 되었다면 서버에서 success라는 문자 올것이다.
  4. 삭제가 되었다면 localStorage에서 삭제를 해준 뒤 로그아웃 성공을 안내한다.
  5. 아니라면 실패 안내만 한다.

마치며

1차 프로젝트 때 로그인, 회원가입 기능 구현도 해보고 싶었으나 다른기능에 욕심이 많아서 하지 못했었다.
2차 때 소셜 로그인이 있다는 얘기를 듣고 이건 꼭 해야겠다는 생각을 했다.
처음 코드를 치려고 하는데 도통 감이 잡히지 않아서 여러 자료들을 보면서 많은 참고들을 했다.
우여곡절 끝에 해냈고 하루면 끝날줄 알았지만 2~3일 정도 붙잡고 있어서 많이 답답했지만 막상 다 하고 나니 무척이나 후련했다.
꼭 해보고 싶었던 로그인 기능 구현 그 중에서 가장 많이 사용되는 소셜 로그인을 해봐 좋은 경험을 한거 같다.

0개의 댓글