상권's

TIL 79 (개인 프로젝트 네이버 로그인 구현) 본문

~2022 작성 글/TIL

TIL 79 (개인 프로젝트 네이버 로그인 구현)

라마치 2022. 4. 20. 19:21

이번에는 개인 프로젝트에서 구현한 네이버 소셜 로그인 기능에 대해서 알아보겠습니다. 개인적으로 네이버 문서가 카카오보다 보기에 더 불편했던 것 같습니다. 그래서 카카오 보다 더 미숙할 것 같은데 양해 부탁드리며, 잘 못된 정보는 알려주시면 바로 수정하겠습니다.

 

네이버 로그인 기능 또한 카카오 로그인처럼 네이버 개발자 센터에 등록 후 이용할 수 있습니다. 네이버 개발자 센터 가기

 

NAVER Developers

네이버 오픈 API들을 활용해 개발자들이 다양한 애플리케이션을 개발할 수 있도록 API 가이드와 SDK를 제공합니다. 제공중인 오픈 API에는 네이버 로그인, 검색, 단축URL, 캡차를 비롯 기계번역, 음

developers.naver.com

먼저 애플리케이션을 먼저 등록합니다.

사용 API로 네이버 로그인으로 설정하고 별명과 이메일 주소를 필수로 체크했으며,

로그인 오픈 API 서비스 환경은 PC웹으로 설정했습니다.

서비스 URL은 현재 개발 중이니 localhost:3000,

콜백 URL은 카카오와 동일하게 클라이언트 단에서 /naver 로 접근해서 처리할 것이기 때문에 localhost:3000/naver로 설정해주었습니다.

이렇게 필요한 부분을 다 작성하며 애플리케이션이 생성되고 Client ID, Client Secret을 확인할 수 있습니다. 이 정보는 로그인 구현에 필요하니 클라이언트에 .env로 저장해서 사용하도록 하겠습니다.

로그인 기능 구현은 '네이버 로그인 API 명세'를 참고했습니다.

네이버 로그인은 카카오와 비슷하게 네이버 회원 인증 & Redirect URL로 code 전송 => 토큰 발급 => 회원 정보 조회 순으로 진행됩니다.

 

 

코드를 보면서 설명해보겠습니다. 카카오 로그인과 동일하게 클라이언트에서 로그인 성공 시 code를 받을 수 있도록 Redirect URL에 이용할 수 있는 임의의 페이지를 만들어줬습니다.

먼저 로그인 페이지입니다. 네이버 로그인 버튼을 쓰지 않고 임의로 만든 버튼에 <a> 태그의 href 속성을 이용했습니다. 네이버의 경우 Client_ID와 Redirect URL 그리고 사용자가 임의로 작성하는 State가 있습니다.

// theMenu/client/src/pages/LoginPage
  const REACT_APP_NAVER_CLIEN_ID = process.env.REACT_APP_NAVER_CLIEN_ID;
  const REACT_APP_NAVER_REDIRECT_URL = process.env.REACT_APP_NAVER_REDIRECT_URL
  const REACT_APP_NAVER_STATE = process.env.REACT_APP_NAVER_STATE
  const NAVER_AUTH_URL = `https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=${REACT_APP_NAVER_CLIEN_ID}&redirect_uri=${REACT_APP_NAVER_REDIRECT_URL}&state=${REACT_APP_NAVER_STATE}`;
 // ..중략..
  return (
    <>
      <div>
 // ..중략..
        <br />
        <button onClick={handleLogin}>
          로그인
        </button>
        <button>
          <a href={KAKAO_AUTH_URL}>카카오 로그인</a>
        </button>
        <button>
          <a href={NAVER_AUTH_URL}>네이버 로그인</a>
        </button>
  // ..중략..

해당 버튼을 눌렀을 때 나오는 네이버 로그인 화면입니다.

 

네이버 회의 인증 성공 시 Redirect URL로 넘어가는 클라이언트 단의 페이지입니다.

// theMenu/client/src/pages/Naver
// ..중략..
export default function Naver ({ setIsLogin, setUserInfo }) {
  const navigate = useNavigate();

  const getUserInfo = () => {  
    let code = new URL(document.location.toString()).searchParams.get("code");
    axios({
        method : 'POST',
        url : 'http://localhost:4000/callback/naver',
        data : {
          code : code
        }
    })
// ..중략..

 

해당 페이지에서 useEffect로 처리할 함수입니다. 카카오와 동일한 방법으로 code값을 얻습니다. 이후의 처리가 카카오 로그인과는 조금 다른데 네이버는 서버의 callback으로 토큰과 사용자의 정보를 응답받습니다.

  naver: async (req, res) => {
    try {
      const NAVER_CLIEN_ID = process.env.NAVER_CLIEN_ID;
      const NAVER_CLIEN_SECRET = process.env.NAVER_CLIEN_SECRET;
      const NAVER_STATE = process.env.NAVER_STATE;
      const getToken = await axios({
        method : 'GET',
        url : `https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id=${NAVER_CLIEN_ID}&client_secret=${NAVER_CLIEN_SECRET}&code=${req.body.code}&state=${NAVER_STATE}`,
      })
      const access_token = getToken.data.access_token;
      const getUserInfo = await axios({
        method: 'GET',
        url : 'https://openapi.naver.com/v1/nid/me',
        headers: {
          Authorization: `Bearer ${access_token}` 
        }
      });
      const userEmail = getUserInfo.data.response.email;
      const userNick = getUserInfo.data.response.nickname;
      const findUser = await UserModel.findOne({
        where: {
          email: userEmail,
          social: 'naver'
        }
      });
      if (!findUser) {
    // ..중략..
      } else {
     // ..중략..      
      }
    }
  }

먼저 토큰을 얻기 위해서는 Client ID, Client Secret, State와 Redirect URL에서 받은 code가 필요합니다(getToken함수). 토큰을 받은 후 getUserInfo함수처럼 Authorization 헤더에 Bearer과 함께 해당 토큰을 담아서 요청을 보내면 사용자 정보를 받을 수 있습니다.

 

이후에는 해당 사용자가 회원가입되어 있는 사용자인지 여부를 확인하고 처리하는 로직을 구현하면 됩니다!

 

이렇게 지난 주말동안 구현했던 카카오와 네이버 로그인 기능을 알아봤습니다. 아직 미숙해서 코드 상에 아쉬운 점들이 있을 수 있습니다. 부족한 부분은 알려주시면 제가 개발자로써 성장하는 데에 큰 도움이 될 수 있으니 편하게 알려주세요. 처음 경험해보시는 분들에게 큰 도움이 되었으면 좋겠습니다.

 

이후에는 개인 프로젝트에서 지도 API를 사용해서 인근에 해당 메뉴를 판매하는 식당을 보여줄 수 있는 서비스를 구현할 예정입니다. 이 또한 빠르게 학습하고 반영해서 공유해보도록 하겠습니다!

 

시연 영상

Comments