[Week2] Kakao Login

tia·2022년 2월 17일
0

파이널프로젝트

목록 보기
5/9

🤡 Kakao Login

1. 카카오 API 등록

카카오 API 등록 링크 접속 후, 카카오 아이디로 로그인
화면 상단에 내 애플리케이션 클릭 후 아래 화면에서 애플리케이션 추가하기 클릭

앱이름과 사업자명 정보 입력후 저장 버튼 클릭!!

그러면 아래와 같이 앱 키가 생성됨 👍🏻

왼쪽 바에서, "플랫폼" 클릭 후 프로젝트 성격에 맞게 플랫폼 등록
우리 프로젝트는 웹프로젝트 이므로 Web 부분에 로컬주소와 배포주소를 추가

여담이지만, 2주 프로젝트 진행시 배포하는 과정에서 엄청 고생한 경험이 있어
이번에는 배포를 미리 시도했고 다행히 성공했다 😁 팀장님 최고!

위의 사진에서 맨 하단에 Redirect URI 등록하러 가기 클릭

api 설정한대로 Redirect URI 설정해주면 카카오 API 등록 완료 🤩

2. client 설정

홈페이지에서 카카오 로그인 버튼을 누르면, 아래 코드가 실행됨

  const handleKakao = () => {
    const KAKAO_LOGIN_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${process.env.REACT_APP_KAKAO_REST_API}&redirect_uri=${process.env.REACT_APP_KAKAO_REDIRECT_URI}&response_type=code`;
    window.location.assign(KAKAO_LOGIN_URL);
  };

Router.js 파일에 아래와 같이 라우트 추가

<Route path="/kakao/signin" element={<Kakao />} />

Kakao.js 파일 설정은 아래와 같이 😎

import { useState, useEffect } from 'react';
import axios from 'axios';
import { useDispatch } from 'react-redux';
import { setSocialUser, socialSignIn } from '../../redux/user/userSlice';
import { useNavigate } from 'react-router-dom';

const KaKao = () => {
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const [token, setToken] = useState();

  const getKakaoCode = () => {
    const kakaoCode = new URL(window.location.href).searchParams.get('code');
    if (kakaoCode) {
      getToken(kakaoCode);
    }
  };

  const getToken = async (code) => {
    try {
      const data = await axios.post('/kakao/signin', {
        code,
      });
      const accessToken = data.data.access_token;
      setToken(accessToken);
    } catch (e) {
      console.log(e);
    }
  };

  const getUserInfo = async (token) => {
    try {
      const data = await axios.get(`/kakao/user?accessToken=${token}`);
      if (data) {
        const { email, name, user_type: who } = data.data.giverInfo;
        dispatch(socialSignIn());
        dispatch(setSocialUser({ email, name, who }));
        localStorage.setItem('token', token);
        navigate('/');
      }
    } catch (e) {
      console.log(e);
    }
  };

  useEffect(() => getKakaoCode(), []);

  useEffect(() => getUserInfo(token), [token]);

  return (
    <>
      <div></div>
    </>
  );
};

export default KaKao;

3. server 설정

router 파일에 아래 내용 추가

router.post('/kakao/signin', user.kakaoLogin.getToken);
router.get('/kakao/user?', user.kakaoLogin.getUser);

kakaoLogin.js 파일 설정은 아래와 같이 😎

'use strict';
const axios = require('axios');
const jwt = require('jsonwebtoken');
const { giver } = require('../../models');

module.exports = {
  getToken: async (req, res) => {
    const code = req.body.code;
    const url = `https://kauth.kakao.com/oauth/token?grant_type=${process.env.KAKAO_GRANT_TYPE}&client_id=${process.env.KAKAO_REST_API}&redirect_uri=${process.env.KAKAO_REDIRECT_URI}&code=${code}&scope=account_email`;
    try {
      const token = await axios.post(url, {
        headers: { 'content-type': 'application/x-www-form-urlencoded' },
      });
      const data = token.data;
      res.send(data);
    } catch (e) {
      console.log(e);
    }
  },
  getUser: async (req, res) => {
    const token = req.query.accessToken;
    const kakaoAPI = 'https://kapi.kakao.com/v2/user/me';
    try {
      const kakaoUser = await axios.get(kakaoAPI, {
        body: {
          property_keys: ['kakao_account.email'],
        },
        headers: {
          'Content-type': 'application/x-www-form-urlencoded;charset=utf-8',
          Authorization: `Bearer ${token}`,
        },
      });

      const user = kakaoUser.data;

      const giverFound = await giver.findOne({
        where: { email: user.kakao_account.email },
      });

      if (giverFound) {
        const giverInfo = giverFound.dataValues;
        delete giverInfo.password;
        const accessToken = jwt.sign(giverInfo, process.env.ACCESS_SECRET);
        res.send({ accessToken, giverInfo });
      } else {
        const newGiver = await giver.create({
          email: user.kakao_account.email,
          name: user.properties.nickname === '' ? '' : user.properties.nickname,
          user_type: 1,
        });
        const { id, email, name, user_type } = newGiver.dataValues;
        const giverInfo = { id, email, name, user_type };
        const accessToken = jwt.sign(giverInfo, process.env.ACCESS_SECRET);
        res.send({ accessToken, giverInfo });
      }
    } catch (e) {
      console.log(e);
    }
  },
};

4. 이미 회원가입이 되어있는 email일 경우

구글 로그인도 마찬가지로, 나같은 경우에 avecjs@gmail.com 계정을 동일하게 구글계정과 카카오계정으로 사용하고 있음
만약에, avecjs@gmail.com 으로 회원가입을 한경우, 구글로그인과 카카오로그인을 시도했을때를 대비해서 코드 수정을 함

위에 server 부분의 kakaoLogin.js 파일 내용을 보면
giverFound 변수가 중복 이메일 체크를 해주는 과정임!

덕분에 이미 회원가입이 되어있는 이메일인 경우, 소셜로그인을 시도해도 새롭게 db에 유저정보가 저장되는 것이 아니라, 회원가입 되어 있는 계정으로 로그인이 가능해졌음 😆

0개의 댓글