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)
댓글 남기기