[탐나BnB] 소셜 로그인 구현하기 #2(feat. Kakao)

Joah·2022년 7월 6일
0

프로젝트-탐나BnB

목록 보기
2/7
post-thumbnail
post-custom-banner

카카오 소셜 로그인 코드 작성

이전 게시글에서 인가코드를 받아오기 위해 Redirect_URI가 필요하다고 언급했다.
이전 게시물 보러가기

인가코드를 받기 위해 어떤 코드를 작성해야 하는지 알아보자


⛳ 카카오 로그인 모달창

과정

  1. 카카오 로그인 버튼을 클릭하면
  2. 인가코드를 받아오기 위해 Redirect_URI로 이동한다.
const KakaoModal = () => {
  const CLIENT_ID = process.env.REACT_APP_CLIENT_ID;
  const REDIRECT_URI = process.env.REACT_APP_REDIRECT_URI;

  const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`;

  const handleLogIn = () => {
    window.location.href = KAKAO_AUTH_URL;
  };

  return (
    <ModalContext>
      <ModalLogoBox>
        <ModalLogoImage src="/images/Logo.png" />
      </ModalLogoBox>
      <ModalText>환영합니다!</ModalText>
      <ModalText>간편한 로그인을 위해</ModalText>
      <ModalText>소셜 로그인을 이용해 주세요.</ModalText>
      <KaKaoBtn onClick={handleLogIn}>
        <KaKaoImage src="/images/kakao_login_medium_wide.png" />
      </KaKaoBtn>
    </ModalContext>
  );
};
  • 우선 process.env.REACT_APP_ 문장을 무시해주길 바란다. 이는 아래의 .env 파일에 대한 이해가 필요하다.
    .env에 대해 알아보기

  • 지금 당장은 아래의 코드로 작성해도 된다. 하지만 .env 파일을 사용하는 것을 권장한다.

  const CLIENT_ID = CLIENT_ID;
  const REDIRECT_URI = REDIRECT_URI;

하지만 CLIENT_ID에 작성된 REST_API 키는 애플리케이션 등록한 사람의 개인정보가 노출될 위험성이 있는 민감한 정보이기 때문에 직접 코드를 작성하기 보다는 .js 파일을 따로 생성하여 관리하는 것을 권장한다.
(해당 이유로 .env를 사용)

return 문 안의 <KakaoBtn onClick={handleLogIn}>

버튼을 클릭하면 사용자가 카카오 로그인을 시작한다는 의미로 인가코드를 요청하고 받아와야 한다.

  const handleLogIn = () => {
    window.location.href = KAKAO_AUTH_URL;
  };
  • 인가코드를 받으려면 Redirect_URI로 이동해야 한다.

  • window.location.href는 현재 웹 브라우저의 주소를 다른 주소로 이동시키는 역할을 한다.

  • KAKAO_AUTH_URL이 할당되어 있는 것을 보니 해당 URL로 이동시키는 함수가 될 수 있다.

  • 즉, <KakaoBtn>을 클릭하면 handleLogIn 함수가 발생한다. 해당 함수는 URL을 이동시키는데 그 주소가 KAKAO_AUTH_URL이 된다.


그럼 KAKAO_AUTH_URL에는 어떤 정보가 담겨 있어야 하나?

카카오 공식 문서에 명시된 내용을 보면 카카오에 인가코드 요청을 위해 URI에 필수로 작성되어야할 사항이 Parameter 표에 작성되어 있다.
client_id, redirect_uri, response_type 세 가지가 있다.
client_id는 REST_API 키이며, redirect_uri에는 내 애플리케이션 등록 시 카카오 로그인 항목에서 작성했던 Redirect URI를 작성하면 된다. response_type"code"로 고정으로 작성하면 된다.

  const CLIENT_ID = process.env.REACT_APP_CLIENT_ID;
  const REDIRECT_URI = process.env.REACT_APP_REDIRECT_URI;

  const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?
client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`;
  • CLIENT_IDREDIRECT_URI를 변수에 할당하여 KAKAO_AUTH_URL 주소에 작성한다. 해당 주소로 이동하면 인가코드를 받아올 수 있다.

  • 주소에 대한 자세한 내용은 블로그를 참고! URL 구조

코드를 해석했으니 다시 이해하자면!

const KakaoModal = () => {
  const CLIENT_ID = process.env.REACT_APP_CLIENT_ID;
  const REDIRECT_URI = process.env.REACT_APP_REDIRECT_URI;

  const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`;

  const handleLogIn = () => {
    window.location.href = KAKAO_AUTH_URL;
  };

  return (
    <ModalContext>
      <ModalLogoBox>
        <ModalLogoImage src="/images/Logo.png" />
      </ModalLogoBox>
      <ModalText>환영합니다!</ModalText>
      <ModalText>간편한 로그인을 위해</ModalText>
      <ModalText>소셜 로그인을 이용해 주세요.</ModalText>
      <KaKaoBtn onClick={handleLogIn}>
        <KaKaoImage src="/images/kakao_login_medium_wide.png" />
      </KaKaoBtn>
    </ModalContext>
  );
};
  • <KakaoBtn>을 클릭하면 onClick 함수가 작동한다.

  • handleLogIn 함수는 주소를 이동시킨다. KAKAO_AUTH_URL

  • KAKAO_AUTH_URL에는 CLIENT_IDREDIRECT_URI가 부여되어야 하며 고유한 CLIENT_ID에 따라 지정된 REDIRECT_URI로 이동했을 때 인가코드가 발급된다.

  • 따라서 <KakaoBtn>을 클릭하면 KAKAO_AUTH_URL로 이동하면서 인가코드를 받을 수 있다.


⛳ 받아온 인가코드 서버에 넘겨주기

KakaoModal.js에서 <KakaBtn>을 클릭하면 위의 이미지인 리다이렉팅 되는 페이지로 넘어가면서 주소에 인가코드가 함께 담겨있다.
REDIRECT_URI 주소인 localhost:3000/users/kakao_signin 다음의 문자열이 인가코드이다. 쿼리스트링이며 물음표로 시작한다.

앞으로 할 일은?
1. 주소창에 적혀있는 인가코드를 추출하여 변수에 담기

  1. 백엔드에서 보내주는 토큰 받아 로컬 스토리지에 저장하기

//Kakao.js

const Kakao = () => {
  const location = useLocation();
  const code = qs.parse(location.search, {
    ignoreQueryPrefix: true,
  }).code;

  useEffect(() => {
    fetch(`http://서버주소:8000/users/kakao-signin?code=${code}`)
      .then(res => res.json())
      .then(data => {
        if (data.access_token) {
          localStorage.setItem('token', data.access_token);
          localStorage.setItem('userImage', data.user_image);
          window.open('http://localhost:3000', '_self');
        } else {
          alert('로그인 실패');
        }
      });
  }, []);

  return (
    <Block>
      <InnerText>Let's go to Jeju✈️</InnerText>
    </Block>
  );
};
  • 주소창에 접근하기 위해서는 useLocation hook을 사용한다.

  • useLocation은 현재 URL 정보를 가져올 수 있다.

  • console에 location.search를 하면 ?를 포함한 QueryString을 반환한다.
    즉, location.search안에는 REDIRECT_URI 주소를 제외한 QueryString이 담긴다. 즉, 인가코드가 담긴다는 뜻!

  • 하지만 꼭 제거해야 하는 부분이 있다면 ?code=이 부분이다. 정확히 하자면 ?code= 다음 문자열부터 인가코드인 것이다.

  • ?code=를 제거하기 위해 qs 라이브러리를 설치했다. npm install qs

const code = qs.parse(location.search, {
    ignoreQueryPrefix: true,
  }).code;
  • qs.parse()는 QueryString인 location.search를 객체로 변환 시켜준다.

  • ignoreQueryPrefix: true?code= 즉, 쿼리스트링의 기본으로 fix 되어 있는 데이터를 무시, ignore해주는 속성이다.

  • 객체의 key 는 code이니 객체에 접근하기 위해서 점 표기법을 사용하여 마지막에 .code를 작성한다.

  • 결과적으로 code라는 변수에는 인가코드만 담기게 되는 것이다.
const code = 인가코드

앞으로 할 일은?
2. 인가코드가 담긴 변수를 백엔드에 넘겨주기

//Kakao.js

  useEffect(() => {
    fetch(`http://서버주소:8000/users/kakao-signin?code=${code}`)
      .then(res => res.json())
      .then(data => {
        if (data.access_token) {
          localStorage.setItem('token', data.access_token);
          localStorage.setItem('userImage', data.user_image);
          window.open('http://localhost:3000', '_self');
        } else {
          alert('로그인 실패');
        }
      });
  }, []);
  • 서버에 넘겨주는 방식은 반드시 백엔드 개발자와 먼저 상의를 해야한다.

  • 백엔드 개발자가 QueryString으로 인가코드를 넘겨달라고 했기 때문에 method : GET으로(생략가능) fetch함수를 작성했다.

  • 이렇게 되면 굳이 qs를 사용할 이유가 없었다. 따라서 반드시 사전에 백엔드와 상의를 해야한다.

  • 인가코드를 보낸 후 받아오는 데이터는 토큰이다.

  • 서버는 클라이언트에서 보낸 인가코드로 카카오 서버에 토큰을 요청한다. 다시 받은 토큰을 클라이언트에 넘겨준다.

  • 받아온 토큰을 로컬스토리지에 저장한다.

개발자 도구의 Application 창의 localStorage session을 보면 'token'이라는 이름으로 토큰이 저장되어 있는 것을 확인할 수 있다.


⛳ Long Story Short

멀고도 험난한 소셜 로그인이 끝이났다. 처음에는 막막했다. 도대체 이걸 나보고 어떻게 하라고..? 공식문서 읽는 것도 멀미나는데 어떻게 이해하라고...?
구글링과 함께 로그인을 구현한 다른 팀원들이 없었다면 지금도 구현하지 못했을 것이다.
너무나도 복잡하고 커보이는 기능도 쪼개고 쪼개서 구현하다보면 어느새 완성된다. 가장 중요한 것은 다른 사람의 코드를 참고하더라도 지금 이 시간처럼 블로그 정리를 통해서 나의 것으로 만드는 과정이다.

profile
Front-end Developer
post-custom-banner

0개의 댓글