카카오 로그인 구현

PRB·2023년 10월 13일
1
post-thumbnail

1. 배경

사이드 프로젝트에 일반 로그인을 구현한 후, 소셜 로그인(Kakao 로그인)을 추가 하려고 했고 Kakao 로그인을 직접 구현하여 Next.js와 next/auth를 사용한 구현 간의 차이를 비교하고자 했습니다.

2. 카카오 로그인 과정


큰 과정은 위 사진을 참고하며 구현하였고 프론트에서 처리할지, 백에서 처리할지 나뉘는데 나는 프론트(next)에서 처리를 하였고 우리 서비스 회원 여부확인만 백엔드로 위임하였다.

a.사용자가 카카오 로그인 클릭

사용자가 카카오 로그인 버튼을 누른다.

b.프론트 -> 카카오 인가서버 카카오 로그인 화면 요청

프론트엔드에서는 카카오 인가 서버에 로그인 페이지를 요청한다.
이때, redirectUri를 정의하여 카카오 디벨로퍼에도 등록한다!

const handleSignWithKaKao = () => {
    const kakao = kakaoInit();
  // 카카오 인가 서버로 인가 코드 요청
    kakao.Auth.authorize({
      redirectUri: `${process.env.NEXT_PUBLIC_APP_HOST_NAME}/callback/kakao/authorize`,
    });
  };

c. 사용자 -> 인가서버 아이디,비번, 동의 체크 완료

사용자는 아이디, 비밀번호 및 동의 항목을 카카오 인가 서버로 전달한다.

d. 인가서버 -> 사용자 인가코드 반환

카카오 인가 서버는 인가 코드를 발급하고 이전에 정의한 redirectUri로 리다이렉트한다.

e. 프론트 -> 인가서버 인가코드 넘김

인가 코드를 받은 후, 프론트 엔드에서 이 인가 코드를 카카오 인가 서버로 전송해야 하고 이 코드는 접근 토큰을 받기 위한 과정이다.

async function fetchAccessToken(code: string): Promise<string> {
  const config = {
    headers: {
      "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
    },
  };

  const data = new URLSearchParams();
  data.append("grant_type", "authorization_code"); // authorization_code로 고정
  data.append("client_id", KAKAO_APP_KEY); // 앱 REST API 키
  data.append("redirect_uri", `${process.env.NEXT_PUBLIC_APP_HOST_NAME}/callback/kakao/authorize`); // 인가 코드를 전달받을 서비스 서버의 URI
  data.append("code", code); // code로 고정

  try {
    const response = await axios.post("https://kauth.kakao.com/oauth/token", data, config);
    return response.data.access_token || "";
  } catch (error) {
    console.error("Failed to fetch access token:", error);
    return "";
  }
}

export const getServerSideProps: GetServerSideProps<AuthorizeProps> = async (context) => {
  const code = Array.isArray(context.query.code) ? context.query.code[0] : context.query.code || "";
  const accessToken = await fetchAccessToken(code);

  const res = await fetchUserFromKakao(accessToken);

  return { props: { userInfo: res.data } };
};

f. 인가서버 -> 프론트 카카오 토큰 반환

카카오 인가 서버는 인가 코드를 확인하고 접근 토큰을 반환합니다. 이 과정은 이미 작성한 코드와 동일하다.

g. 프론트 -> 리소스서버 토큰 넘김

프론트 엔드는 받은 접근 토큰을 리소스 서버로 전송한다.
이 토큰은 리소스 서버에서 사용자 정보를 가져오기 위한 권한을 부여해준다.

export const getServerSideProps: GetServerSideProps<AuthorizeProps> = async (context) => {
  const code = Array.isArray(context.query.code) ? context.query.code[0] : context.query.code || "";
  
    // 인가 코드를 사용하여 접근 토큰을 가져옴
  const accessToken = await fetchAccessToken(code);

    // 접근 토큰을 사용하여 사용자 정보를 가져옴
  const res = await fetchUserFromKakao(accessToken);

  return { props: { userInfo: res.data } };
};

h. 리소스서버 -> 프론트 사용자 정보 반환

리소스 서버는 접근 토큰이 유효한 경우, 사용자 정보를 프론트 엔드에 반환한다.

i. 프론트 -> 백 사용자 식별

프론트엔드는 받은 사용자 정보를 사용하여 백엔드 서버에 사용자를 식별 요청을 전송한다. 사용자가 있다면 로그인 시켜주고 없다면 회원가입 처리 후 로그인 시켜준다.

const Authorize = ({ userInfo }: AuthorizeProps) => {
  useEffect(() => {
    signInOrSignUpKakao();
  }, []);

  const signInOrSignUpKakao = async () => {
    const res = await authApi.kakaoLogin(userInfo.id);

    if (res.message === "OK") {
      window.location.assign(`${process.env.NEXT_PUBLIC_APP_HOST_NAME}/explore`);
    }
  };

  return <h2>로그인 중입니다..</h2>;
};

3. 미 해결 과제

카카오 로그인을 통해 회원가입한 경우, 사용자의 닉네임, 관심사, MBTI와 같은 추가 정보를 입력받지 않아 문제가 발생하고 있어서 현재는 백엔드에서 임의의 데이터를 생성하고 사용자가 나중에 수정할 수 있는 방식으로 문제를 해결했다.
추후에는 아래와 같은 방법으로 문제를 해결하고자 한다.

  1. 카카오 로그인 후 추가 정보 입력 페이지 이동
  2. 카카오 로그인 정보와 추가 정보 통합
  3. 회원가입 완료
profile
사용자 입장에서 사용자가 원하는 것을 개발하는 프론트엔드 개발자입니다.

0개의 댓글

관련 채용 정보