DataUSA에는 제대로 된 로그인 페이지도, 더불어 소셜 로그인 기능도 없지만 DataWeSA에는 멋진 로그인 페이지와 소셜 로그인 기능까지 갖춰져있다^^
레이아웃 짜주신 효식님께 박수10번..👏👏👏
소셜 로그인 기능 구현을 경험해보기 위해 우리 팀은 각자 하나씩 맡아서 진행하기로 했다. 나는 그중에서 구글 소셜 로그인을 맡았다.
OAuth 2.0
구글 소셜 로그인 기능 구현 하면 가장 먼저 등장하는 단어이다. OAuth는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 산업 표준 프로토콜이다.(wikipedia)
OAuth는 이전의 인증방식들의 보안이 취약하다는 단점을 보완하여 탄생했으며 현재는 표준안으로 발표되어 널리 사용되고 있다.
OAuth 2.0의 핵심은 구글, 페이스북, 카카오 등 다양한 클라이언트 환경에 적합한 인증 및 권한의 위임 방법을 제공하고, 그 결과로 클라이언트에게 access_token을 발급하는 것이다. 그리고 발급받은 Access Token을 이용해 타사의 API 서비스를 이용할 수 있다.
Oauth의 인증방식은 다음과 같다.
구글 로그인으로 빗대어 살펴보면 사이트에 접속 후 "Login with Google" 버튼을 클릭하면 구글 로그인 창으로 이동하고, 로그인이 성공하면 해당 사이트의 접근을 허용할 것인지 창이 생성된다. 이후 허용을 누르면 사이트에서 로그인 목적으로 사용할 수 있는 토큰을 구글이 발급해주고 발급받은 토큰을 이용하여 만료기간 전까지 서비스를 사용할 수 있다.
Oauth개념은 처음에 무척 헷갈리기 때문에 여러번 반복해서 과정을 살펴보고 강의를 듣는 것도 좋은 듯 하다. 생활코딩 Oauth 강의
이렇게 인증 프로세스에 관해 어느정도 이해가 완료되었다면 구글 API발급 사이트에 접속하여 프로젝트를 생성한다.
원하는 이름으로 프로젝트를 생성하고 API 및 서비스로 이동하여 사용자 인증 정보에 들어간다.
여기서 OAuth 클라이언트 ID를 클릭하여 애플리케이션 유형을 웹 애플리케이션으로 해주고, 이름을 자유롭게 지정해준 뒤 승인된 자바스크립트 출처 및 리디렉션 uri를 입력해준다.(나는 로컬사이트에서 테스트해봐야 했으므로 로컬 사이트를 적어주었다)
저장하면 클라이언트 ID 와 클라이언트 보안 비밀이 발급되는데, 보안 비밀은 절대 유출하면 안된다..!! (때문에 화면 생략)
그리고 클라이언트 ID는 잘 복붙해놔야 한다.
소셜 로그인은 라이브러리를 활용하여 쉽게 구현할 수 있다.
라이브러리를 사용하여 구글 로그인 구현하기-npmjs사이트
그러나! 라이브러리를 사용하지 않고 구글 로그인을 경험해보는 일이 목적이므로 나는 다시 열심히 구글링을 하였다.
구글 로그인을 구현하기 위해서는 SDK를 활용해야한다. SDK는 Software Development Kit의 약자로 프로그래머들을 위해서 제공하는 개발도구들이다.
SDK안에는 개발에 도움이 될 개발 도구 프로그램, 디버깅 프로그램, 문서, API 등이 있다.
잠깐✋ API 참고문서 : API가 뭔가요?(비개발자용) by조영수님
SDK로 google api를 불러오고 내 클라이언트 ID를 입력한다음 로그인창을 구현하면 바로 사용자 정보를 불러올 수 있다.
먼저 index.html에 아래와 같은 코드를 입력하여 플랫폼 파일을 불러오고
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
내 클라이언트 ID를 포함한 meta 태그도 추가해준다.
구글 Developer 사이트 참고
function Google() {
const googleLoginBtn = useRef(null);
const [token, setToken] = useState("");
useEffect(() => {
googleSDK();
}, []);
//SDK 초기 설정 및 내 API초기화
const googleSDK = () => {
window.googleSDKLoaded = () => {
console.log(window.gapi);
window.gapi.load("auth2", () => {
const auth2 = window.gapi.auth2.init({
client_id:
"내 클라이언트 ID",
scope: "profile email",
});
//버튼 클릭시 사용자 정보 불러오기
auth2.attachClickHandler(
googleLoginBtn.current,
{},
(googleUser) => {
const profile = googleUser.getBasicProfile();
console.log(profile);
console.log(`Token || ${googleUser.getAuthResponse().id_token}`);
setToken(googleUser.getAuthResponse().id_token);
console.log(`ID: ${profile.getId()}`);
console.log(`Name: ${profile.getName()}`);
console.log(`Image URL: ${profile.getImageUrl()}`);
console.log(`Email: ${profile.getEmail()}`);
},
(error) => {
alert(JSON.stringify(error, undefined, 2));
}
);
});
};
//구글 SDK 불러오기
(function (d, s, id) {
let js;
const fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.id = id;
js.src = "https://apis.google.com/js/platform.js?onload=googleSDKLoaded";
fjs.parentNode.insertBefore(js, fjs);
})(document, "script", "google-jssdk");
};
return (
<GoogleBtn id="gSignInWrapper">
<span class="label" />
<div ref={googleLoginBtn} id="customBtn" className="customGPlusSignIn">
<span className="icon"></span>
<span className="buttonText">Login with Google</span>
</div>
</GoogleBtn>
);
}
...styled-component로 GoogleBtn 커스텀
Building a custom Google Sign-In button
SDK를 활용하여 사용자의 정보(id, name, profile image, email 그리고 token)를 불러오는데 성공하였다. 이후 백엔드와의 통신으로 받은 토큰을 가지고 우리 토큰으로 발급하는 방법을 살펴보려고 한다.
const GoogleApiPOST = (token) => {
axios
.get(`${socialLoginAPI}/user/google`, {
headers: {
Authorization: token,
"Content-Type": "application/json",
},
})
.then((res) => {
sessionStorage.setItem("token", res.data.token);
alert("로그인 되었습니다");
history.push("/home");
})
.catch((error) => alert("Error가 발생하였습니다", error));
};
config.js파일로 백엔드 ip주소를 관리하여 변경될 때마다 수월하게 바꿔 줄 수 있도록 하였다.
axios post 메소드를 사용하여 token을 headers로 보내고 다시 백엔드로부터 받은 token을 sessionStorage에 저장하여 페이지를 닫을 경우에 초기화 되도록 구현하였다.
로그인이 완료되면 알림창과 함께 메인페이지로 이동하도록 구현하였다.
감사합니다 지영님 💙 간밤에 많은 도움이 되었어요~