Config.js
export const HOST = "http://localhost:3000"; export const KAKAO_CLINT_ID = "카카오 클라이언트 ID"; export const KAKAO_CALLBACK_URL = `${HOST}/oauth/callback/kakao`; export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_CLINT_ID}&redirect_uri=${KAKAO_CALLBACK_URL}&response_type=code`; export const NAVER_CLIENT_ID = "네이버 클라이언트 아이디"; // 발급 받은 Client ID 입력 export const NAVER_CALLBACK_URL = `${HOST}/oauth/callback/naver`; // 작성했던 Callback URL 입력
URL 설정
App.js
<Route path="/oauth/callback/kakao" element={<AuthKakaoLoginHandler />} /> <Route path="/oauth/callback/naver" element={<AuthNaverLoginHandler />} />
NaverLoginHandler.js
import { useEffect, useRef, useState } from 'react' import styled from 'styled-components' import logo from '../../../assets/images/navericon.png'; import { useDispatch } from 'react-redux'; import { useNavigate, useParams, useLocation } from 'react-router-dom'; import { loginUserNaver } from "../../../_actions/user_actions"; import { NAVER_CLIENT_ID, NAVER_CALLBACK_URL } from "../../Config"; // 기존 로그인 버튼이 아닌 커스텀을 진행한 로그인 버튼만 나타내기 위해 작성 const NaverIdLogin = styled.div` display: none; ` const NaverLoginBtn = styled.a` display: flex; align-items: center; width: 350px; height: 50px; background-color: #03c75a; border-radius: 6px; margin-top: 20px; border: 0; cursor: pointer; ` // 로그인 버튼 사용가이드 링크를 들어가면 이미지를 받아 이렇게 적용이 가능하다 ! const NaverIcon = styled.div` width: 30px; height: 30px; margin-left: 10px; background: url(${logo}) no-repeat center; background-size: 30px; ` const NaverLoginTitle = styled.span` margin-left: 90px; color: ${({ theme }) => theme.White}; font-weight: 600; font-size: 14px; line-height: 24px; color: #fff; ` const NaverLoginHandler = ({ setGetToken, setUserInfo }) => { const dispatch = useDispatch(); const naigate = useNavigate(); const naverRef = useRef(); const { naver } = window; const location = useLocation(); const [accessToken, setAccessToken] = useState(); const initializeNaverLogin = () => { const naverLogin = new naver.LoginWithNaverId({ clientId: NAVER_CLIENT_ID, callbackUrl: NAVER_CALLBACK_URL, // 팝업창으로 로그인을 진행할 것인지? isPopup: false, // 버튼 타입 ( 색상, 타입, 크기 변경 가능 ) loginButton: { color: 'green', type: 3, height: 50 }, callbackHandle: true, }); naverLogin && naverLogin.init(); naverLogin && naverLogin.getLoginStatus(async function (status) { //console.log("status : ", status); if (status) { // 아래처럼 선택하여 추출이 가능하고, const email = naverLogin.user.getEmail() const name = naverLogin.user.getName() // console.log("1 네이버 로그인 ", email, name); naverLoginProcess(email, name, naverLogin.user.profile_image); } }); } //3.네이버 정보를 이용해서 서버에 로그인 처리 async function naverLoginProcess(email, name, image) { if (!email) { alert("이메일 정보 제공은 필수 입니다."); return; } let dataToSubmit = { email: email, name: name, image: image, oauth2: "naver" }; dispatch(loginUserNaver(dataToSubmit)) .then(response => { if (response.payload.loginSuccess) { window.localStorage.setItem('userId', response.payload.userId); // console.log("loginSuccess :", response.payload); naigate("/"); } else { console.log("로그인 실패 :"); } }) .catch(err => { console.log("에러 :", err); }); } // 네이버 소셜 로그인 (네아로) 는 URL 에 엑세스 토큰이 붙어서 전달된다. // 우선 아래와 같이 토큰을 추출 할 수 있으며, // 3부에 작성 될 Redirect 페이지를 통해 빠르고, 깨끗하게 처리가 가능하다. const userAccessToken = () => { window.location.href.includes('access_token') && getToken() } const getToken = () => { const token = window.location.href.split('=')[1].split('&')[0] // console.log, alert 창을 통해 토큰이 잘 추출 되는지 확인하자! // 이후 로컬 스토리지 또는 state에 저장하여 사용하자! // localStorage.setItem('access_token', token) // setGetToken(token) } // 화면 첫 렌더링이후 바로 실행하기 위해 useEffect 를 사용하였다. useEffect(() => { if (location.hash) { const str = location.hash.split("="); console.log(str[1]); setAccessToken(str[1]); handleNaverLogin(); } }, []) // handleClick 함수 onClick 이벤트 발생 시 useRef 를 통해 지정한 naverRef 항목이 클릭 된다. // current 를 통해 아래 div 태그의 ref={} 속성을 줄 수 있다. ( 자세한 내용은 공식문서를 확인하자. ) const handleNaverLogin = () => { if (naverRef.current.children[0]) { console.log(" handleNaverLogin 1"); naverRef.current.children[0].click(); } console.log(" handleNaverLogin 2"); initializeNaverLogin(); userAccessToken(); // NaverLogin.getLoginStatus(async function (status) { // console.log("status : ", status); // if (status) { // // 아래처럼 선택하여 추출이 가능하고, // const email = NaverLogin.user.getEmail() // const name = NaverLogin.user.getName() // console.log("네이버 로그인 ", email, name); // // 정보 전체를 아래처럼 state 에 저장하여 추출하여 사용가능하다. // //console.log(email, name, naverLogin.user.profile_image); // naverLoginProcess(email, name, NaverLogin.user.profile_image); // } // }); } return ( <> {!accessToken && <NaverIdLogin ref={naverRef} id="naverIdLogin" />} {!accessToken && <NaverLoginBtn onClick={handleNaverLogin}> <NaverIcon alt="navericon" /> <NaverLoginTitle>네이버로 로그인</NaverLoginTitle> </NaverLoginBtn>} </> ) } export default NaverLoginHandler;
LoginPage.js
{/* 네이버 로그인 버튼 */} <NaverLoginHandler />
nodjs 로그인 참조
/**6. 네이버 로그인 처리 */ router.post("/login/naver", (req, res) => { //1)요청한 이메일을 DB 에서 찾는다. User.findOne({ email: req.body.email }, (err, user) => { if (!user) { //2)등록 처리 const user = new User(req.body); console.log("저장할 user :", user); user.save((err, doc) => { if (err) return res.json({ success: false, err }); console.log("등록 처리 후 Token 생성 "); // Token 생성 user.generateToken((err, user) => { if (err) return res.status(400).send(err); //토큰을 쿠키에 저장한다. res.cookie("w_authExp", user.tokenExp); res.cookie("w_auth", user.token) .status(200) .json({ loginSuccess: true, userId: user._id }); }); }); return; } //5)등록된 유저가 있다면 바로 Token 생성 user.generateToken((err, user) => { if (err) return res.status(400).send(err); //6)토큰을 쿠키에 저장한다. res.cookie("w_authExp", user.tokenExp); res.cookie("w_auth", user.token) .status(200) .json({ loginSuccess: true, userId: user._id }); }); }); });
이미지 다운로드
https://github.com/braverokmc79/ouath2-img
참조 :
https://developers.naver.com/docs/login/devguide/devguide.md#네이버%20로그인-개발가이드
https://velog.io/@rxxdo/리액트로-네이버-소셜-로그인-적용하기-1부-네아로-적용하기
댓글 ( 4)
댓글 남기기