회고/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>
);
};
// 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
나름 시간 많이 투자했는데... 아직 많이 부족하다 나는.
카카오와 네이버 로그인은 파이어베이스에서 제공하는 구글 로그인과 다르게 각각 디벨로퍼스에 들어가 설정을 해주어야 하는데 주말 혹은 차후에 정리해야겠다.