[쉘위헬스] React 네아로(네이버아이디로그인) 구현

해달·2021년 12월 9일
6

Project_ShallWeHealth

목록 보기
6/15

프로젝트에서 OAuth 로그인 구현방식을 네이버와 카카오 두개를 진행하자고 결정 되어서 카카오를 선행으로 연결하고
네이버를 후에 구현 하였는데, 구현하는 과정속에서 많이 헤매어서 정리해놓으려고 한다.
참고한 블로그에서 좋은 정보들을 많이 얻을 수 있었다


(1) 네이버 애플리케이션등록

https://developers.naver.com/apps/

양식에 맞춰서 애플리케이션을 등록하면 위에 보이는 2개의 값을 얻을 수 있다


(2) 네이버 기본가이드 읽어보기

(3) 구현시작

맨 처음시작은 튜토리얼에 있는 javascript 코드와 node.js 코드를 읽어보고
구글링을 하여서 이미 구현되어있는 예제코드들을 많이 확인하였다

  • React index.html에 로그인 SDK 연결

애플리케이션을 설정 할 때 Callback URL 을 지정해주었어야 했는데
이 URL은 네이버 로그인 연동에 동의 하였을 경우 동의정보를 가지고 Callback URL로 이동한다

이 말인 즉슨 유저가 동의를 눌러서 생성 된 정보를 가지고 작업 할 위치를 지정해주면 된다
나같은 경우에는 Naver 컴포넌트를 만들어서 App에 path 등록을 해준 뒤 callback url로 지정해 주었다

<Route path='/naver' component={NaverLogin} />

callback url에 연결 된 컴포넌트는 기능동작만 한다고 생각하면 편하다!

만약 callback url을 잘못 작성하였다면 로그인버튼 클릭 시

  • 이와같이 로그인 에러가 뜬다 (#에러1)

네이버로그인 연동 URL 설정하기


//네이버 제공 sample code
https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=CLIENT_ID&state=STATE_STRING&redirect_uri=CALLBACK_URL

요청 URL로 네이버에서 알려준 sample code로

로그인연동 URL 생성을 생성해서 함수에 담아주었고 버튼 클릭 시 실행하게 되면 전달받는 내용은 아래와 같다고 가이드에 명시되어있다.

네이버 로그인과 정보 제공 동의 과정이 완료되면 콜백 URL에 code값과 state 값이 URL 문자열로 전송됩니다. code 값은 접근 토큰 발급 요청에 사용합니다.
API 요청 실패시에는 에러 코드와 에러 메시지가 전송됩니다.

  • Callback 응답 정보
  • API 요청 성공시 : http://콜백URL/redirect?code={code값}&state={state값}
  • API 요청 실패시 : http://콜백URL/redirect?state={state값}&error={에러코드값}&error_description={에러메시지}

위에 내용으로 로그인연동 동의과정 수행 후 동의정보를
포함하여 콜백 URL로 전달이 된다.

(콜백 URL로 내용 전달을 받고) 3.4.4 접근 토큰 발급 요청

Callback으로 전달받은 정보를 이용하여 접근 토큰을 발급받을 수 있습니다. 접근 토큰은 사용자가 인증을 완료했다는 것을 보장할 수 있는 인증 정보입니다.
Callback으로 전달받은 'code' 값을 이용하여 '접근토큰발급API'를 호출하게 되면 API 응답으로 접근토큰에 대한 정보를 받을 수 있습니다.
'code' 값을 이용한 API호출은 최초 1번만 수행할 수 있으며 접근 토큰 발급이 완료되면 사용된 'code'는 더 이상 재사용할수 없습니다.

위에 내용으로 가이드에서 안내를 해주고 location 을 이용하여서 url에서 값을 추출해 올수 있다

const location = useLocation();

const code = location.search.split('=')[1];
const state = location.search.split('=')[2];

출력한 값을 가지고 token을 요청해서 받아오면 된다

//sample code
https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id=jyvqXeaVOVmV&client_secret=527300A0_COq1_XV33cf&code=EIc5bFrl4RibFls1&state=9kgsGTfH4j7IyAkg  

그런데 cors 에러가 뜨기 시작했고 토큰을 받아와서 최종적으로 유저정보를 받아 올 수가 없었다 (내가 못한걸지도)


실제 구현 한 로직

구글링 후 찾아보니 윈도우 객체에 있는 네이버에 로그인 함수를 이용하여 토큰 값을 바로 전달 받을 수 있는 방법이 있어서
이미 구현되어있던 로그인 컴포넌트에 아래 함수를 추가하고 useEffect로 로그인 모달이 뜰 시 랜더링 되도록 하였다

const NaverLogin = () => {
  const { naver } = window

  const naverLogin = new naver.LoginWithNaverId(
    {
      clientId: process.env.REACT_APP_NAVER_CLIENT_ID,
      callbackUrl: process.env.REACT_APP_REDIRECT_URI,
      isPopup: false, /* 팝업을 통한 연동처리 여부, true 면 팝업 */
      loginButton: { color: "green", type: 1, height: 47 } /* 로그인 버튼의 타입을 지정 */
    }
  );

  naverLogin.init();
}


  useEffect(() => {
    initializeNaverLogin(); // useEffect로 안하고 onclick하면 로그인배너아이콘 안뜸
  }, []);

그리고 아이콘이 표시 될 div태그에 id='naverIdLogin' 을 꼭 추가해주어야 한다

추가해주지 않으면 Cannot read properties of null (reading 'firstChild') #에러2 를 만날 수 있다

<div className="grid-naver" id='naverIdLogin'></div>

3.4.5 접근 토큰을 이용하여 프로필 API 호출하기

위에서 적용 된 함수가 잘 실행이 되면 지정해두었던 callback url로
아래와 같이 url을 가지고 이동하게 되고

http://{callback url}
#access_token= { token value }
&token_type=bearer
&expires_in=3600

url에서 token 값을 location을 이용하여 뽑아낸 뒤
서버에 axio요청을 보내면
서버측에서 token 값을 전달받아 접근 토큰을 이용하여 프로필 API 호출하기 를 할 수 있게 된다
클라이언트 측에서는 cors에러가 난다


const location = useLocation();  

const getNaverToken = () => {
    if (!location.hash) return;
    const token = location.hash.split('=')[1].split('&')[0]; //token 출력
    axios.post(`${process.env.REACT_APP_SERVER_API}/user/naver-login`, {
        token
    }, {
        withCredentials: true
    })
    .then((res)=> {
        window.location.replace('/')
      //서버측에서 로직이 완료되면 홈으로 보내준다
    })
  };


  useEffect(() => {
    getNaverToken();
  }, []);

서버 코드구현

초기에는 작성되어 있는 예제들을 참고하여 axios 요청 안에서 request요청을 보내었는데 401로 유저를 찾을 수 없다는 err를 전달 받았다.

axios 요청 안에서 한번 더 서버로 요청을 보낼 수 있다는 사실을 몰라서 여기저기 찾아보았는데 사용 할 수 있었던 것으로 확인이 되었고
네이버에서 안내해준 양식대로 get 요청으로 유저 데이터를 받아 올 수 있었다.

    const { token } = req.body // client에서 전달받은 token
    const userData = await axios.get('https://openapi.naver.com/v1/nid/me', {
        headers : {
            'Authorization' : `Bearer ${token}`,
        }
    })
    
... //회원가입 및 로그인 로직 구현

받아온 데이터로 회원가입 및 로그인 기능 구현 끝!!!


마치며,

모든내용을 정리하고 보니 네이버로그인 개발가이드 문서가 굉장히 될어있다고 생각이 든다
하지만 처음 적용하려고 하니 로직 이해가 조금 느렸었다
다른분들의 블로그들을 정말 많이 보았는데도 불구하고 중반까지 계속 헤매었지만 결론적으로 정말 잘 이해하게 된 것 같다
혹여나 다른분들이 검색하여서 들어왔을 때 조금의 도움이 되었으면한다
axios 안에서 axios 요청을 한번 더 보낼 수 있었다는 사실만 조금 빨리 알았으면 좋았을거 같아서 아쉽다 🥲


etc
초반에 블로그에 작성되어 있던 로직을 보면서 진행하였다 (네이버 개발가이드 로직과 같음)

naver Login 함수를 이용하면서 code로 token을 받아오는 부분이 빠지고 아래와 같이 진행하게 되었다


참고한 블로그

0개의 댓글