생각보다 네이버 로그인 오픈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
나는 일단 로컬호스트 3000으로 진행했다.
(+) 찾아보니 소셜 로그인을 도와주는 라이브러리도 있긴 하다. 네이버, 카카오 등등 많이 있음.
이때 이름을 REACTAPP 으로 시작하지 않으면 값을 읽지 못해 undefined가 나온다.
REACT_APP_NAVER_CLIENT_ID 이렇게 길~게 네이밍할수밖에 없었음..ㅜㅜ
이때 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>
먼저 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
이 저장되있는 것을 확인할 수 있다.
로그인 버튼이 눌리고 사용자가 확인을 눌렀을때 콜백페이지로 넘어간다. 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' } }));