사내에서 임시로 개발된 프로젝트를 리액트와 장고로 다시 만들고, 기능을 추가하여 MVP를 만드는 역할을 맡게 되었다. 추가하기로 한 기능 중에 처음 얘기가 나온 것이 소셜로그인이다.
소셜로그인은 이미 운영 중인 서비스 계정을 활용하여, 여러가지 서비스를 이용할 수 있도록 하는 기능이다. 서비스를 이용하는 유저들의 접근성을 향상시키고, 유저의 개인정보 보안 역할을 큰 서비스에서 대신하도록 만들 수 있다. 우리 서비스의 경우, 안드로이드와 IOS를 주 대상으로 하기 때문에 구글로그인과 애플로그인을 필수적으로 추가할 계획이다. 오늘은 그 중 구글로그인 연결을 위한 방법을 탐구해 보았다.
구글로그인을 활용하기 위해서는 구글 클라우드 플랫폼을 통해 OAuth2.0 클라이언트 ID를 발급받아야 한다.
위 과정은 로컬환경에서 테스트 용도로 최소한의 내용만 입력하여 발급받는 것이므로, 필요한 내용은 추가로 입력해야한다. 발급받은 클라이언트ID는 리액트의 구글ID 로그인 동작과 함께 정보 요청할 때 발송하게 된다.
소셜로그인을 구현하는 방법은 크게 두 가지다. 하나는 클라이언트 사이드에서 플랫폼과 정보를 주고 받는 것이고, 다른 하나는 서버사이드에서 정보를 주고 받는 것이다.
클라이언트 사이드는 1) 클라이언트에서 정보를 플랫폼에 발송 2) 플랫폼에서 클라이언트로 토큰 발송 3) 클라이언트에서 서버로 토큰 전달 4) 서버에서 토큰을 가지고, 플랫폼에 유저 정보를 요청 5) 유저 정보와 서버에서 생성한 자체 토큰을 클라이언트로 전달하는 과정으로 진행된다.
서버 사이드는 1) 클라이언트에서 정보를 플랫폼에 발송 2) 플랫폼에서 서버로 토큰 발송 3) 서버에서 토큰을 가지고 플랫폼에 정보 요청 4) 유저 정보와 서버에서 생성한 자체 토큰을 클라이언트로 전달하는 과정으로 진행된다.
클라이언트 사이드로 구현하면, 단순하고 직관적으로 정보를 주고받기 때문에, 손쉽게 로그인을 구현할 수 있다.
하지만 클라이언트 사이드로 구현한 경우에는 몇 가지 한계가 있다. 첫째, 유저가 클라이언트를 사용하고 있을 경우에만 구글 API에 접근할 수 있다. 즉, 사용자가 웹 앱을 떠나면, 작업이 중단될 수 있다. 서버 사이드로 구현한 경우에는 사용자 대신 백그라운드 작업을 수행할 수 있다. 둘째, 구글 iframe이 특수 쿠키를 사용하여 구글 계정을 표시하므로, 브라우제어서 타사 쿠키를 비활성화한 경우 로그인이 동작하지 않을 수 있다.
클라이언트 사이드 구현은 gapi와 react-google-login을 활용하였다. gapi는 구글이 제공하는 서비스에 쉽게 접근할 수 있도록, 클라이언트에서 사용할 수 있도록 만들어놓은 자바스크립트 라이브러리이다. react-google-login은 리액트에서 구글 로그인을 연결하도록 구현해놓은 라이브러리다. 해당 라이브러리를 활용해 구글 GoogleButton이라는 컴포넌트를 만들고, 해당 컴포넌트를 페이지에 띄웠다.
App.js
GoogleButton.js
GoogleButton컴포넌트를 보면 react-google-login의 속성 값인 cliendId는 구글 클라우드 플랫폼에서 발급받은 cliendId, onSuccess는 로그인 성공 시 동작, onFailure는 실패 시 동작으로 설정할 수 있다. 위의 코드의 경우 onSuccess와 onFailure는 GoogleLogin 컴포넌트로부터 response값을 받아 출력하는 동작만 실행한다. useEffect()훅을 활용하여, 컴포넌트 렌더 시 실행되는 코드가 중요한데, start()라는 함수를 인자로 갖는 gapi.load()함수이다. start함수의 경우, gapi의 고객 정보값을 설정하는 것으로 보이고, gapi.load()함수는 클라이언트 인증 종류를 설정하는 것으로 보인다.
빈 화면에 달랑 버튼만 구현했다.
구글버튼을 누르면 이렇게 익숙한 로그인 모달이 띄워진다. 정상적으로 로그인 과정을 진행하면, 아래와 같이 성공하여 받아온 정보를 콘솔창에서 확인할 수 있다.
해당 데이터 중에 토큰을 받아 서버에 HTTP 통신으로 넘겨주면, 클라이언트 사이드로 구현할 때 프론트엔드의 역할은 끝나는 것이다.
추가 작성
도메인 값을 추가할 때는 사용자 인증 정보에 가서 추가할 수 있다!
추가 작성2(22.08.02)
클라이언트 사이드 인증방식 VS 서버 사이드 인증방식
클라이언트 사이드 인증방식은 비교적 쉽게 구현할 수 있다. 해당 플랫폼의 로그인 API를 끌어와 요청하는 정보들을 담아 HTTP Request만 보내면, Response 값으로 원하는 데이터 값을 확인할 수 있다.
클라이언트 사이드 인증방식은 OAuth2 흐름 을 사용할 때 다양한 제한 사항이 발생한다. 예를 들면, 특정 플랫폼의 경우 사용자가 페이지를 방문하지 않을 때의 API 통신이 불가능하고, 더 민감한 API에 액세스할 수 없으며, 사용자를 위해 더 보호된 정보를 가져올 수 없다. 이는 플랫폼에서 안전한 방법으로 이 작업을 수행하도록 요구하기 때문에 예상되는 결과다. 이를 수행하는 유일한 안전한 방법은 서버 사이드 인증방식을 사용하는 것이다.
구글소셜로그인 - 리액트&장고 1
구글소셜로그인 - 리액트&장고 2
시간적 여유가 생기면, 해당 코드를 뜯어보고 정확한 동작과 구현을 공부해보아도 좋을 것 같다.
참고자료
혹시 리액트로 서버사이드 구글로그인을 구현하려면 어떻게 해야할까요??인가코드 받는것까지도 모두 서버에서 하도록 하고 싶어서요!