카카오 로그인 - REST API 사용하기

Gaeun·2023년 2월 4일
1

wecode TIL

목록 보기
22/24
post-custom-banner

0. 카카오 로그인?


위 이미지는 카카오 로그인 과정 시퀀스 다이어그램이다. 내가 이해한 방식으로 정리하자면 인가 코드 → 토큰 → 사용자 정보를 카카오를 통해 받는 과정이며, 회원가입과 로그인이 완료되었을 때 JWT을 프론트에 전달하는 것까지 이번 프로젝트에서 구현하였다.

1. 카카오 로그인 구현

1-1. Kakao Developer 등록하기

  1. Kakao Developer 에서 로그인 애플리케이션을 등록하고,
  2. 사이트 도메인과 Redirect URI를 설정해준 뒤, (나는 localhost:3000, http://localhost:3000/auth/kakao/callback 로 설정해놓았다.)
  3. 동의 항목을 설정하고
  4. REST_API 키를 환경 변수로 관리하면 초기 설정은 끝이다.

또한 보안 강화를 위해 Client Secret을 설정해줄 수 있다.

1-2. 코드 작성하기

// controller.js
const kakaoLogin = asyncErrorHandler(async (req, res) => {
  const authCode = req.query.code; // 프론트에서 authCode를 전달 받아온다!

  if (!authCode) throwCustomError("MISSING_AUTH_CODE", 400); // authCode를 받아오지 못할 경우 분기 처리

  const accessToken = await userService.kakaoLogin(authCode); // service단에 authCode 가지고 가서 JWT 만들기

  return res.status(200).json({ accessToken }); // 그리고 JWT를 프론트에 전달!
});

// service.js
const SocialTypeId = Object.freeze({
  KAKAO: 1,
  NAVER: 2,
  GOOGLE: 3,
}); // 프로젝트가 끝난 뒤, Naver와 Google 로그인도 구현해보고 싶어 일단 추가해놓았다. 

const kakaoLogin = async (authCode) => {
  try {
    const getKakaoToken = await axios.get(
      "https://kauth.kakao.com/oauth/token",
      {
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        params: {
          grant_type: "authorization_code",
          client_id: process.env.KAKAO_REST_API_KEY,
          redirect_url: process.env.KAKAO_REDIRECT_URI,
          code: authCode,
        },
        withCredentials: true,
      }
    ); // client_id와 redirect_url은 .env에서 관리, params에 authCode를 포함하여 보내서 카카오 서버에서 authCode 검증. 이후 카카오 서버에서 access_token을 보내준다. 

    const getKakaoUserData = await axios.get(
      "https://kapi.kakao.com/v2/user/me",
      {
        headers: {
          Authorization: `Bearer ${getKakaoToken.data.access_token}`,
        },
      }
    ); // 받아온 access_token을 다시 카카오 서버에 보내서 userData를 받아온다. 

    const socialId = getKakaoUserData.data.id;
    const email = getKakaoUserData.data.kakao_account.email;
    const nickname = getKakaoUserData.data.properties.nickname;
    const socialTypeId = SocialTypeId.KAKAO;

    const userInfo = await userDao.getUserInfo(socialId, socialTypeId);

    // 해당 사용자가 가입한 기록이 없는 경우 회원가입을 하고 JWT를 발급
    if (!userInfo) {
      const newUser = await userDao.createUser(
        socialId,
        email,
        nickname,
        socialTypeId
      );

      const accessToken = jwt.sign(
    	. . .  
      );

      return accessToken;
    }
	
    // 가입 기록이 있는 경우 로그인 후 JWT 발급
    const accessToken = jwt.sign(
      . . .
    );

    return accessToken;
  } catch (err) {
    const error = new Error("ERROR_OCCURED_WHILE_ATTEMPING_TO_LOG_IN");
    error.statusCode = 400;
    throw error;
  }
};
profile
🌱 새싹 개발자의 고군분투 코딩 일기
post-custom-banner

0개의 댓글