I T H

[MySchedule project] 13. 카카오 로그인 구현 (2) - Backend 본문

React + Node.js

[MySchedule project] 13. 카카오 로그인 구현 (2) - Backend

thdev 2024. 2. 12. 12:12
이번 챕터는 카카오로 로그인하기 backend 로직을 구현하겠다.
- frontend에서 받아온 인가코드를 가지고 토큰을 받아오고, 그 토큰을 가지고 사용자 데이터를 받아온다.
- 카카오 공식문서 참고

 

- 코드 작성에 들어가기 앞서 User 컬렉션( = 테이블)에 컬럼 "loginType"을 추가했다.

Backend

[ src / models / User.js ]  - 코드추가

 loginType: {
    type: Number,
    default: 0,
  },

 

 

[ src / routes / login.js ]  - 코드추가

 

1. 토큰 발급

 

- 카카오 공식문서에 있는 예제이다. rest_api_key와 redirect_uri 그리고 인가코드를 axios를 통해 

post 방식으로 보내주면 토큰을 발급 받을 수 있다.

카카오 공식문서 예제 - 토큰 받아오기

 

- 데이터를 보낼때는 axios와 qs를 사용했다.

- qs는 api url에 값을 전달할때 string 값으로 만들어서 보낼 수 있도록 도와주는 모듈이다. 예를 들어서 json 형식으로 되어 있는 파라미터들을 string 형식으로 파싱해준다. 

- 파싱 (parsing) : 원하는 데이터를 추출하여 가공하기 쉬운상태로 만들어 줌

const axios = require("axios");
const qs = require("qs");

 

 

2. 토큰으로 사용자 데이터 받아오기

 

- 토큰으로 사용자 데이터를 받아올 수 있다.

- 해당 url로 토큰을 header에 담아 get방식으로 보내준다.

카카오 공식문서 예제 -사용자 데이터 받아오기

 

- 받아온 사용자 데이터는 db에 저장하고 토큰과 사용자데이터를 프론트로 전달해준다.

//kakao Login
router.post("/kakaoLogin", async (req, res, next) => {
  console.log(req.body);
  const code = req.body.authorizationCode; //인가 코드
  let tokenData = "";
  let kakaoUserData = {}; //kakao 유저 데이터

  //토큰 받아오기
  try {
    tokenData = await axios({
      method: "POST",
      url: "https://kauth.kakao.com/oauth/token",
      headers: {
        "content-type": "application/x-www-form-urlencoded",
      },
      data: qs.stringify({
        grant_type: "authorization_code",
        client_id: process.env.KAKAO_REST_API_KEY,
        redirectUri: process.env.KAKAO_REDIRECT_URI,
        code: code,
      }),
    });

    console.log(tokenData);
  } catch (error) {
    console.error(error);
    return;
  }

  // 사용자 데이터 받아오기
  try {
    kakaoUserData = await axios({
      method: "GET",
      url: "https://kapi.kakao.com/v2/user/me",
      headers: {
        Authorization: `Bearer ${tokenData.data.access_token}`,
      },
    });
  } catch (error) {
    console.error(error);
    return;
  }
  console.log("==================");
  console.log(kakaoUserData.data);
  const userData = kakaoUserData.data;
  const accessToken = tokenData.data.access_token;

  //DB에 저장
  //type : 0 일반로그인, 1: 카카오 로그인 2: 네이버 로그인
  const kakaoUserInfo = {
    userId: userData.id,
    userName: userData.kakao_account.profile.nickname,
    loginType: 1,
  };

  const userCheck = await User.findOne({ userId: userData.id });

  if (userCheck) {
    return res.json({ accessToken: accessToken, role: 0, kakaoUserInfo });
  } else {
    const user = new User(kakaoUserInfo);
    await user.save();
    return res.json({
      accessToken: accessToken,
      role: 0,
      kakaoUserInfo,
    });
  }
});

 

 

[ 결과화면 ] 

토큰 받아옴
사용자 데이터 받아옴

 

 

Frontend

[ src / store / userSlice.tsx ]  - 코드추가

 

- 백앤드에서 사용자 데이터와 토큰을 받았으면 리덕스 스토어와 로컬스토리지에 넣어주자.

.addCase(Kakao_userLogin.pending, (state) => {
        state.isLoading = true;
      })
      .addCase(Kakao_userLogin.fulfilled, (state, action) => {
        state.isLoading = false;
        state.isAuth = true;
        state.userData.role = action.payload.role;
        state.userData.userId = action.payload.kakaoUserInfo.userId;
        state.userData.userName = action.payload.kakaoUserInfo.userName;
        state.userData.loginType = action.payload.kakaoUserInfo.loginType;
        localStorage.setItem("accessToken", action.payload.accessToken);
        toast.info("메인페이지로 이동합니다.");
      })
      .addCase(Kakao_userLogin.rejected, (state, action: any) => {
        state.isLoading = false;
        state.error = action.payload;
        toast.error(action.payload);
      });