[React] 네이버로그인

KoEunseo·2023년 3월 7일
0

project

목록 보기
29/37
post-thumbnail

생각보다 네이버 로그인 오픈api 사용방법 정보가 많지 않고 복잡한 것 같아서 더듬더듬 해보면서 기록하려고 한다.

네이버 로그인 api 튜토리얼
https://developers.naver.com/docs/login/web/web.md
네이버 open API 가이드 깃허브
https://github.com/naver/naver-openapi-guide/blob/master/sample/nodejs/APIExamNaverLogin.js

1. 일단 네이버 오픈API에 내 앱을 등록한다.

나는 일단 로컬호스트 3000으로 진행했다.
(+) 찾아보니 소셜 로그인을 도와주는 라이브러리도 있긴 하다. 네이버, 카카오 등등 많이 있음.

2. .env 파일을 만들어서 client id를 저장해준다.

이때 이름을 REACTAPP 으로 시작하지 않으면 값을 읽지 못해 undefined가 나온다.
REACT_APP_NAVER_CLIENT_ID 이렇게 길~게 네이밍할수밖에 없었음..ㅜㅜ

3. index.html에 script를 하나 추가한다.

이때 public 폴더에 있는 index.html에 직접 추가해도 되고,
컴포넌트 하나 만들어서 dom으로 직접 건드려도 될 것 같다.
나는 간단히 전자를 택했다.

<script type="text/javascript" 
        src="https://static.nid.naver.com/js/naveridlogin_js_sdk_2.0.2.js" 
        charset="utf-8"></script>

4. NaverLogin 버튼을 불러온다.

먼저 window에서 naver를 가져오길래 어떻게 생겼나 콘솔에 찍어봤다. 이전단계에서 html에 작성했던 sdk를 가져오는 듯. 버전이 2.0.2인 것을 확인할 수 있었다.

네이버에서 제공하는 샘플페이지에서 "naverIdLogin"으로 id를 주고 있음.

네이버 로그인 API 명세 예시 중

<!-- 네이버 로그인 버튼 노출 영역 -->
    <div id="naver_id_login"></div>
    <!-- //네이버 로그인 버튼 노출 영역 -->

그리고 id를 주었을때 개발자도구로 확인해보면 아래와 같이 나오는 것을 확인할 수 있다.

<div id="naverIdLogin">
  <a>
    <img src="https://static.nid.naver.com/oauth/big_g.PNG?version=js-2.0.1" height="48">
  </a>
</div>

LoginWithNaverId 이 메서드에 대한 건 어디나와있는걸까... 네이버 깃허브에 들어가봐도 안나온다. 웹은 없고 ios랑 android 리포지토리만 있음..

  • 네이버로그인 sdk에서 확인할 수 있었다.
const { naver }: any = window;

const NaverLogin = () => {
  const clientId = process.env.REACT_APP_NAVER_CLIENT_ID;
  const callbackUrl = '콜백할url';

  const initializeNaverLogin = () => {
    const naverLogin = new naver.LoginWithNaverId({
      clientId,
      callbackUrl,
      isPopup: true,
      loginButton: { color: "green", type: 3, height: "48" },
    });
    naverLogin.init();
  };
  useEffect(() => {
    initializeNaverLogin();
  }, []);
          //네이버 로그인 버튼 노출 영역
  return <div id="naverIdLogin"></div>;
          //네이버 로그인 버튼 노출 영역
};

여기까지 했을때 개발자도구의 Application에서 보면 com.naver.nid.oauth.state_token이 저장되있는 것을 확인할 수 있다.

5. 로그인 버튼 눌렀을때 콜백

로그인 버튼이 눌리고 사용자가 확인을 눌렀을때 콜백페이지로 넘어간다. window.location 이런거 안써도 저절로 넘어감. 이때 네이버 디벨로퍼 페이지에서 내가 설정한 콜백url로 이동된다. url 변경하면 네이버에서도 변경해줘야 에러가 안난다.
로그인버튼이랑 똑같은 초기화작업을 또 한다. getLoginStatus를 통해 로그인상태를 확인한다. 콜백페이지로 리다이렉트되면 한번만 실행되도록 useEffect에 빈배열을 주었다.
그리고 확인해보면 로컬스토리지에 따로 엑세스토큰을 저장할 필요 없이 com.naver.mid.access_token이 저장되어있는 것을 확인할 수 있다!

import { useEffect } from "react";
const { naver }: any = window;

const NaverCallback = () => {
  const clientId = process.env.REACT_APP_NAVER_CLIENT_ID;
  const callbackUrl = "http://localhost:3000/login";

  const initializeNaverLogin = () => {
    const naverLogin = new naver.LoginWithNaverId({
      clientId,
      callbackUrl,
      isPopup: false,
      callbackHandle: true,
    });
    naverLogin.init();

    naverLogin.getLoginStatus(function (status: any) {
      if (status) {
        var email = naverLogin.user.getEmail();
        if (email === undefined || email === null) {
          alert("이메일은 필수정보입니다. 정보제공을 동의해주세요.");
          naverLogin.reprompt();
          return;
        }
      } else {
        console.log("로그인 실패");
      }
    });
  };

  useEffect(() => {
    initializeNaverLogin();
  }, []);
  
  return <div>네이버 로그인 성공</div>;
};
export default NaverCallback;

로컬호스트에서만 해서 배포를 하면 cors 에러가 날 게 분명하다. 이전에 팀 프로젝트할때 구글로그인 하면서 팀원분이 많이 고생하셨음...

실제로 로그인하면 요런 에러가 22개나 뜬다... OMG

Indicate whether to send a cookie in a cross-site request by specifying its SameSite attribute
Because a cookie’s SameSite attribute was not set or is invalid, it defaults to SameSite=Lax, which prevents the cookie from being sent in a cross-site request. This behavior protects user data from accidentally leaking to third parties and cross-site request forgery.
Resolve this issue by updating the attributes of the cookie:
Specify SameSite=None and Secure if the cookie should be sent in cross-site requests. This enables third-party use.
Specify SameSite=Strict or SameSite=Lax if the cookie should not be sent in cross-site requests.
  • 서버에서 아래와 같이 sameSite 설정을 해주어야 한다고 chat gpt가 말했다...
app.use(session({
  secret: 'my-secret',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true, sameSite: 'none' }
}));
profile
주니어 플러터 개발자의 고군분투기

0개의 댓글