카카오 로그인시 원래 페이지로 되돌아오지 않습니다

977205

현재 아래의 스크립트를 사용중입니다.

<script src="https://developers.kakao.com/sdk/js/kakao.js">

그리고 Nextjs에서 아래와같이 KakaoBtn 컴포넌트를 만들어서 사용중입니다.

import axios from 'axios';
import { useRouter } from 'next/router';
import useSWR from 'swr';
import Image from "next/image";
import kakao from "@public/icons/kakao.png";
import { useEffect } from 'react';

declare global {
  interface Window {
    Kakao: any;
  }
}

interface IProps {
  className: string;
  is_signup: boolean;
}

export default function KakaoBtn({ className, is_signup }: IProps) {
  const { mutate } = useSWR('/api/user');
  const router = useRouter();

  const APP_KEY = <앱키>;
  useEffect(() => {
    const { Kakao } = window;
    if (!Kakao) {
      const script = document.createElement('script');
      script.src = 'https://developers.kakao.com/sdk/js/kakao.min.js';
      script.async = true;
      document.body.appendChild(script);
      // return () => document.body.removeChild(script);
    }
  }, []);

  const kakaoAuth = async () => {
    const { Kakao } = window;
    if (Kakao) {
      if (!Kakao.isInitialized()) {
        Kakao.init(APP_KEY);
      }

      if (is_signup) {
        try {
          await Kakao.API.request({
            url: '/v1/user/unlink',
          });
        } finally {
          kakaoLogin(Kakao);
        }
      } else {
        kakaoLogin(Kakao);
      }
      // Kakao.Channel.addChannel({ channelPublicId: '_eixhCG' });
    }
  }
  const kakaoLogin = (Kakao: any) => {
    Kakao.Auth.login({
      success: async () => {
        console.log('kakao login success');

        Kakao.API.request({
          url: '/v2/user/me',
          success: async (res: any) => {
            console.log('kakao login success res', res);

            const kakao_account = res.kakao_account;
            let phone_number = kakao_account.phone_number;
            if (phone_number) { /*
              * kakao api returns '+82 10-...'
              */
              phone_number = phone_number.trim();
              if (phone_number.startsWith("+82")) {
                phone_number = phone_number.replace('+82', '').trim();
              }
              if (phone_number.startsWith("10")) {
                phone_number = `0${phone_number}`;
              }
              phone_number = phone_number.replaceAll("-", "").trim();
            }

            console.log('kakao_account', kakao_account);

            const body = {
              type: 'kakao',
              id: res.id + '',
              phone_number: phone_number,
              nickname: kakao_account.profile.nickname,
              is_signup,
            };
            if (is_signup) {
              const { data: { channels } } = await axios({
                url: `https://kapi.kakao.com/v2/api/talk/channels?target_id=${res.id}&target_id_type=user_id&channel_ids=_eixhCG&channel_id_type=channel_public_id`,
                method: 'get',
                headers: {
                  'Content-Type': 'application/json',
                  'Authorization': 'KakaoAK <키>',
                },
              });
              let ad_agree = false; // "BLOCKED"
              if (channels) ad_agree = channels[0].relation == "ADDED" ? true : false;

              Object.assign(body, { ad_agree });

              // @ts-ignore
              window.ChannelIO('updateUser', {
                profile: {
                  mobileNumber: phone_number,
                  name: kakao_account.profile.nickname,
                },
                tags: ["간편가입연동"],
                unsubscribeEmail: !ad_agree,
                unsubscribeTexting: !ad_agree,
              }, function onUpdateUser(error: any, user: any) {
                if (error) {
                  console.error('updateUser', error);
                }
              });
            }
            console.log('body', body);


            const { data: { msg }, } = await axios.post('/api/login', body);

            console.log('msg', msg);

            if (msg == 'phone_number exists') {
              alert("이미 가입된 아이디가 있습니다.");
            } else if (msg == 'need to signup') {
              try {
                await Kakao.API.request({
                  url: '/v1/user/unlink',
                });
              } finally {
                is_signup = true;
                kakaoLogin(Kakao);
              }
            } else {
              is_signup = false;
              const {
                data: { token, profile },
              } = await axios.get('/api/user');
              mutate({ ok: true, token, profile });
            }
          },
          fail: (e: any) => {
            console.log(e);
          },
        });
      },
      fail: (e: any) => {
        console.log(e);
      },
    });
  }

  return (
    <div
      onClick={kakaoAuth}
      className={className}
    >
      <div className="relative w-[40px] h-[40px] mt-[4px]">
        <Image
          src={kakao}
          layout='fill'
          objectFit='cover' />
      </div>
      {is_signup ? "카카오로 3초만에 가입" : "카카오로 3초만에 로그인"}
    </div>
  );
}

그런데 다음과 같은 문제가 있습니다. PC상에서는 문제가 없는데 모바일 브라우저에서 카카오 로그인을 실행하면 카카오톡으로 넘어갔다가 돌아오는 것 까지는 문제가 없는데 되돌아왔을때 로그인 실행했던 페이지가 아니라 아래의 페이지가 화면에 표시되어 멈춰있습니다.

https://kauth.kakao.com/public/widget/login/kakaoLoginWidget.html?xdm_e=https%3A%2F%2Fsingle-fire-copy.vercel.app&xdm_c=lq8y8oivei&xdm_p=1

브라우저 메뉴를 이용해서 뒤로가기를 해보면 로그인은 완료된 상태입니다. 이 문제를 해결하기 위해서 어떤 부분을 검토해야 할지 문의드립니다. 감사합니다.

(1) Kakao.Auth.login 는 구버전에서 제공하는 팝업방식 로그인으로 현재 JS SDK v2에서는 더이상 제공하지 않습니다.
리다이렉트 방식 카카오 로그인 사용을 권장드립니다.

참고. [rest api 예제] next.js- 카카오 로그인, 카카오 친구목록 조회, 메시지 발송

(2) Kakao.Auth.login 는 CORS 처리를 위해 동적 객체 생성으로 카카오측과 통신합니다. 해당 객체가 훼손되면 결과를 수신할 수 없고 기재하신 URL은 화면에 표시되야할 객체가 아니나 화면에 표시된 것은 개발하신 시스템상 발생하는 현상으로 보입니다. 단순 HTML 페이지에서 정상 동작 테스트 해보시면 좋을 것 같습니다.

아쉽지만, 개발하신 시스템 종속적인 프론트엔드 문제이므로 확인해드릴 방법이 없습니다.

Nextjs 사용하셔서 서버측 구현도 가능하시니
위 (1)번 리다이렉트 방식 Kakao.Auth.authorize 로 구현 해보시면 어떨까요?