React

 

 

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부-네아로-적용하기

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

자식은 자기의 것이면서 내 것이 아니다. 그러나 이미 나누어져 있기에 또한 인류 속의 사람이다. 자기 것일진대 더욱 교육에 의무를 다하고 그들에게 자립할 수 있는 능력을 길러 주어야 하고 또 내 것이 아니기에 해방시켜야 하고 모든 것을 그들 자신의 것으로 해주어야 하며 하나의 독립인으로 만들어야 한다. -노신

댓글 ( 4)

댓글 남기기

작성