회고/TIL

TIL - 20230213

k1mwnjn 2023. 2. 14. 11:13

 

 

 

소셜 로그인 중 남은 두 가지. 카카오와 네이버.

주말을 포함해 오늘도 종일 노력했지만 아... 쉽지 않다.

로그인 기능 까지만 마무리.

 

// naver login

import React, { useEffect, useRef, useState } from "react";
import {
  NaverLoginItem,
  SocialLoginItem,
  SocialLoginLogo,
  SocialLoginLogoImg,
} from "./style";

export const NaverLogin = () => {
  const [userName, setUserName] = useState("");
  const { naver } = window;
  const naverRef = useRef();
  const NAVER_CLINET_ID = "발급받은 client id";
  const NAVER_CALLBACK_URL = "http://localhost:3000/";

  const initializeNaverLogin = () => {
    const naverLogin = new naver.LoginWithNaverId({
      clientId: NAVER_CLINET_ID,
      callbackUrl: NAVER_CALLBACK_URL,
      isPopUp: false, // pop-up login
      loginButton: { color: "green", type: 1, height: 70 }, // button type
      callbackHandle: true,
    });
    naverLogin.init();
    // 1. 선언된 naverLogin 을 이용하여 사용자 정보를 불러오는데, 함수 내부에서 naverLogin 을 선언하여 지역변수 처리가 되므로 userinfo 정보를 추출하는 것은 지역변수와 같은 함수에서 진행해야 함.

    naverLogin.getLoginStatus(async function (status) {
      if (status) {
        const userid = naverLogin.user.getEmail();
        const username = naverLogin.user.getName();
        setUserName(username);
      }
    });
    // 2. 이처럼 로그인한 사용자 정보를 직접 접근하여 추출 가능함. 이 때, 데이터는 첫 연동 시 동의한 데이터만 추출 가능함.
    // 정보 전체를 state 에 저장하여 추출 -> 사용. ex) setUserInfo(naverLogin.user);
  };

  const userAccessToken = () => {
    window.location.href.includes("access_token") && getToken();
  };
  // 3. 네이버 소셜 로그인은 URL 에 액세스 토큰이 붙어서 전달됨. 위의 형태로 토큰을 추출.

  const getToken = () => {
    const token = window.location.href.split("=")[1].split("&")[0];
    // console.log("token", token);
  };

  // 4. console.log(), alert() 를 통해 토큰이 추출 되는지 확인할 것. 되었다면 이후 local storage 나 state 에 저장하여 사용.
  // localStorage.setItem('access_token', token)
  // setGetToken(token)

  useEffect(() => {
    initializeNaverLogin();
    userAccessToken();
  }, []);

  // 로그인
  const handleNaverLogin = () => {
    naverRef.current.children[0].click();
  };
  return (
    <div id="naverIdLogin" ref={naverRef}>
      <NaverLoginItem onClick={handleNaverLogin}>
        <SocialLoginLogo>
          <SocialLoginLogoImg
            src={require("../../assets/social-login-naver.png")}
          />
        </SocialLoginLogo>
      </NaverLoginItem>
    </div>
  );
};

참고 : https://velog.io/@rxxdo/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A1%9C-%EB%84%A4%EC%9D%B4%EB%B2%84-%EC%86%8C%EC%85%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-1%EB%B6%80-%EB%84%A4%EC%95%84%EB%A1%9C-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

 

// kakao login

import React, { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import axios from "axios";
import reactQuerystring from "react-querystring";
import { SocialLoginItem, SocialLoginLogo, SocialLoginLogoImg } from "./style";

export const KakaoLogin = () => {
  const location = useLocation();
  const REST_API_KEY = "발급받은 key"; // 카카오 디벨로퍼 -> 내 애플리케이션
  const REDIRECT_URI = "http://localhost:3000/"; // callback 받을 주소
  const link = `https://kauth.kakao.com/oauth/authorize?client_id=${REST_API_KEY}&redirect_uri=${REDIRECT_URI}&response_type=code`; // 클릭 시 실행될 링크
  const CLIENT_SECRET = "발급받은 client secret"; // 카카오 로그인 -> 보안
  const KAKAO_CODE = location.search.split("=")[1]; // 주소창의 파라미터(코드 값)

  const [nickName, setNickName] = useState();
  const [profileImage, setProfileImage] = useState();
  const [accessToken, setAccessToken] = useState();

  // 로그인
  const handleKakaoLogin = () => {
    window.location.replace(link);
  };

  //   const code = new URL(window.location.href).searchParams.get("code"); // 로그인 완료 -> 주소창의 파라미터(코드 값) 가져오는 함수
  //   console.log(code);

  //   // access token 요청하기
  //   const getUser = async () => {
  //     const ACCESS_TOKEN = await fetch("https://kauth.kakao.com/oauth/token", {
  //       method: "POST",
  //       headers: {
  //         "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
  //       },
  //       // 액세스 토큰을 요청하기 위해 필요한 친구들
  //       body: reactQuerystring.stringify({
  //         grant_type: "authorization_code",
  //         client_id: REST_API_KEY, // 상단 변수 지정
  //         redirect_uri: REDIRECT_URI, // 상단 변수 지정
  //         code: KAKAO_CODE, // 상단 변수 지정
  //         client_secret: CLIENT_SECRET, // 상단 변수 지정
  //       }),
  //     })
  //       .then((res) => res.json())
  //       .catch((error) => console.log("error:", error));

  //     console.log("ACCESS_TOKEN1", ACCESS_TOKEN);
  //     setAccessToken(ACCESS_TOKEN.access_token); // state 에 access token을 넣어주기
  //     console.log("ACCESS_TOKEN2", ACCESS_TOKEN.access_token);

  //     localStorage.setItem("token_for_kakaotalk", ACCESS_TOKEN.access_token); // local storage에 잘들어가는지 확인

  //     //kakao user DATA를 get해오기
  //     const user = await axios.get("https://kapi.kakao.com/v2/user/me", {
  //       headers: {
  //         //access_token이 필요하다
  //         Authorization: `Bearer ${ACCESS_TOKEN.access_token}`,
  //       },
  //     });

  //     console.log(user); // 값을가져오면 state에 닉네임과 프로필이미지를 string 으로 담아주기
  //     setNickName(user.data.properties.nickname);
  //     setProfileImage(user.data.properties.profile_image);
  //   };
  //   console.log(nickName, profileImage);

  //   useEffect(() => {
  //     getUser();
  //   }, []);

  //   // 로그아웃
  //   const handleKakaoLogout = async () => {
  //     const islogout = await fetch("https://kapi.kakao.com/v1/user/logout", {
  //       headers: {
  //         // accessToken 만료시키기
  //         Authorization: `Bearer ${accessToken}`,
  //         "Content-Type": "application/x-www-form-urlencoded",
  //       },
  //       method: "POST",
  //     }).then((res) => res.json());

  //     localStorage.clear(); // local storage 에 넣어주었던 값 clear
  //     console.log("isLogout", islogout);
  //   };

  //   // 토큰의 유효성 검사 (토큰이 유효한지 검사를 꼭 해보고 배포할 것) 남은 시간 및 고유 id 값 출력
  //   const cheak = async () => {
  //     const cheaktoken = await fetch(
  //       "https://kapi.kakao.com/v1/user/access_token_info",
  //       {
  //         headers: {
  //           Authorization: `Bearer ${accessToken}`,
  //         },
  //       }
  //     ).then((res) => res.json());
  //     console.log("cheaktoken", cheaktoken);
  //   };

  return (
    <SocialLoginItem onClick={handleKakaoLogin}>
      <SocialLoginLogo>
        <SocialLoginLogoImg
          src={require("../../assets/social-login-kakao.png")}
        />
      </SocialLoginLogo>
    </SocialLoginItem>
  );
};

//   <button type="button" onClick={handleKakaoLogout}>
//     로그아웃하기
//   </button>
//   <button type="button" onClick={cheak}>
//     토큰상태확인
//   </button>

참고 : https://dbdudwo126.tistory.com/95

 

나름 시간 많이 투자했는데... 아직 많이 부족하다 나는.

카카오와 네이버 로그인은 파이어베이스에서 제공하는 구글 로그인과 다르게 각각 디벨로퍼스에 들어가 설정을 해주어야 하는데 주말 혹은 차후에 정리해야겠다.