NEXT.JS 13을 이용한 카카오 소셜 로그인 구현

kyubhin Han·2023년 2월 17일
5

bookmore

목록 보기
1/2

Next.js 13을 이용하여 fullStack Web application을 개발 중입니다. 먼저 Web의 로그인으로 kakao login 기능을 구현해보기로 하였습니다.

이전 프로젝트에서 프론트 단에서 카카오 로그인을 구현하는 부분을 만들어보았기 때문에 이번에는 백 단에서 어떻게 구현할 지에 초점을 맞추어 진행하였습니다.

next.js를 처음 사용해보았고, 백 단도 처음으로 구현해보는 것이라 헤맨 부분이 많았습니다. 따라서 여기에 자세히 적음으로써 다음에 구현할 때 참고해보고 이를 보시는 분도 참고가 되었으면 좋겠습니다.

참고 자료
카카오 소셜 로그인 공식 문서
Next js api 공식 문서

구현 로직


기본적으로 kakao developer에 나온 rest api를 사용하여 로그인하는 과정을 따라서 구현해보았습니다. 따라서 공식 문서에 나온 아래 사진을 참고하여 각 과정을 어떻게 구현하였는지 자세히 적어보겠습니다.

Step 0. 준비하기


Next js 준비

먼저 next.js로 프로젝트를 만들어주었습니다. 이때 next.js의 boilerplate인 yarn create next-app --typescript 을 사용하여 초기 설정을 해주었습니다.
참고 : next js 시작하기

그리고 파일 directory 구조를 아래와 같이 만들어주었습니다. 이때 중요한 점은 next.js의 api를 사용하기 위해서 반드시 pages 폴더 내의 api 폴더를 만들고 그 안에 파일을 만들어야 동작한다는 점입니다.(처음에 src 폴더 내의 pages 폴더를 만들고 그 안에 api를 만드니 api를 인식하지 못하는 에러가 발생했습니다.)

따라서 결론적으로 app 폴더 내의 signin 폴더에 카카오 로그인 버튼을 만들어 주었고, 이와 관련된 api를 pages-api-signincheck 폴더 내에 만들어주었습니다.

카카오 준비

서비스 내에서 카카오 로그인을 사용하기 위해 카카오 개발자 사이트에서 서비스를 등록해주었고, 이와 관련된 redirect uri까지 설정해주었습니다. 자세한 내용은 검색하면 많이 나오기 때문에 여기에서는 간단하게 관련된 공식 사이트만 첨부하겠습니다.
카카오 공식 문서


Step 1. 인가코드 받기


인가 코드 받기에서 가장 중요하게 보았던 것은 클라이언트가 클라이언트 서버로 요청을 보내면 이를 클라이언트 서버가 카카오 auth 서버로 보내고 다시 그 인가 코드를 클라이언트 서버가 받는다는 점입니다.

구글에 참고해보기 위해 검색해보니 다른 분들은 대부분 클라이언트가 인가 코드를 받고 이를 다시 서버로 넘겨주는 형태로 개발을 진행하였습니다.

하지만 이렇게 개발하면, 클라이언트가 무의미하게 한 번 더 개입하는 것이고 이에 따라 에러가 발생할 수 있는 시도가 늘 뿐이라 생각하여 이렇게 개발하지 않고 공식 문서에 쓰여 있는 대로 개발하고자 하였습니다.

이를 위해 필요했던 개념이 redirect 개념이었습니다. 클라이언트가 서버로 로그인 요청을 보내면 이를 다시 카카오 Auth Server로 redirect 보내고 그 결과를 다시 서버로 redirect 받아주면 되었습니다.

next js에서 redirect를 어떻게 하는지 검색해보니, next.config.js에서 redirect 하는 방법이 주로 나왔는데, 하지만 api 내에서 조건에 따라 redirect 시켜야 되기 때문에 해당 방법은 사용할 수 없었습니다.

어떻게 해야 할 지 검색해보다가 공식 문서를 살펴보니 자세히 나와 있었습니다.(역시 공식 문서..) 따라서 이를 참고하여 구현해주었습니다.(https://nextjs.org/docs/api-routes/response-helpers)

app/signin/pages.tsx 코드

"use client";

import React from "react";
import styles from "./signin.module.css";
//여기서 반드시 form으로 감싸주어야 signincheck 부분에서 받을 수 있었다.
const page = () => {
  return (
    <div className={styles.Container}>
      <form method="POST" action="/api/signincheck">
        <button type="submit">카카오 로그인</button>
      </form>
    </div>
  );
};

export default page;

pages/api/signincheck/index.ts 코드

import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const url =
    "https://kauth.kakao.com/oauth/authorize?client_id=${CLIENTCODE}&redirect_uri=http://localhost:3000/api/signincheck/callback&response_type=code";
  if (req.method === "POST") {
    res.redirect(307, url);
  } else {
    res.redirect(307, "http://localhost:3000");
  }
}

Step 2.3. token으로 사용자 정보 받기


step 1에서 받아준 코드를 이용해서 토큰을 받아줍니다. 이때 post의 params로 넘겨야 하는데, response의 body로 계속해서 데이터가 넘어가서 에러가 발생했었었습니다. axios post의 사용법을 제대로 모르고 있어서 발생한 문제였습니다. post로 넘길 때 반드시 중간에 null을 넣어서, 데이터는 보내지 않는다고 명시해줍시다!!

토큰을 성공적으로 받았다면 이를 이용해서 사용자 정보를 받아오면 됩니다. 여기에서도 카카오 공식 문서에 나온 것과 같이 작성해서 처리해주면 됩니다.

app/api/signincheck/callback.ts 코드

import type { NextApiRequest, NextApiResponse } from "next";
import axios from "axios";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { code } = req.query;

  if (code) {
    const url = "https://kauth.kakao.com/oauth/token";
    try {
      // 카카오 토큰 받기
      const { data } = await axios.post(url, null, {
        params: {
          grant_type: "authorization_code",
          client_id: `${clientId}`,
          redirect_uri: "http://localhost:3000/api/signincheck/callback",
          code,
        },
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
      });
      const { access_token, refresh_token } = data;

      // 사용자 정보 조회하기(이메일이랑 프로필 이미지 검색)
      const infoResult = await axios.post(
        "https://kapi.kakao.com/v2/user/me",
        null,
        {
          headers: {
            Authorization: `Bearer ${access_token}`,
            "Content-Type": "application/x-www-form-urlencoded",
          },
        }
      );
      const email = infoResult.data.kakao_account.email;
      const profileImage = infoResult.data.properties.profile_image;
  } else {
    res.status(200).json({ error: "code가 없습니다." });
  }
}

정리


여기에서는 next js를 이용하여 카카오 로그인을 하여서 사용자의 정보를 불러오는 것까지 구현하였습니다. 다음 post에서는 이 정보를 이용하여 서비스의 회원 가입 처리 및 access token 및 refresh token을 발급해주는 것까지 구현해보겠습니다.

profile
프론트엔드 취업을 준비 중입니다.

0개의 댓글