Google OAuth 로그인 구현

조소복·2022년 4월 29일
16
post-custom-banner

OAuth 로그인이란?

어떤 사이트에서 회원가입이나 로그인을 하려고 할 때 SNS 로그인 버튼이 있는 것을 볼 수 있다. 이러한 로그인을 우리는 OAuth 로그인이라고 부른다.

백엔드와 프론트엔드에서 이 로직을 어떻게 처리하는지 설명하는 포스팅이다.

구글 공식 문서를 보면 사용자가 Request token을 주면 구글에서 인가 코드를 보내준다.

그러면 사용자는 인가 코드를 이용해서 Access Token을 달라고 요청하고

그 토큰을 이용하여 구글 로그인을 수행하는 로직이다.

하지만 이대로는 이해가 잘 되지 않으니 프론트와 백엔드를 이용하여 좀 더 자세한 로직을 설명하려 한다.

위 이미지를 참고하면 흐름은 다음과 같다.

1. 프론트엔드에서 OAuth 로그인을 요청한다.
2. 구글 서버에서 인가코드를 발행한다 (Access Token)
3. 받은 인가 코드를 백엔드에 보내준다.
4. 인가코드를 이용하여 구글 서버에 사용자의 정보를 요청한다.
5. 올바른 인가코드를 받은 구글 서버는 해당 사용자의 정보를 제공한다.

이러한 로직을 이용하여 실제로 코드를 짜보자.

Google Cloud Platform

우선 구글서버의 인가코드를 받기위해서는 어플리케이션을 등록해야한다.

  • 구글 클라우드 플랫폼에 접속하여 프로젝트를 만든다.
  • 왼쪽을 열어서 API 및 서비스 > OAuth 동의 화면 을 들어간다.

  • 앱의 이름과 개발자 연락처 정보 등을 입력해주고 다음으로 넘어가서 필요한 정보의 범위를 선택해준다.

  • 테스트 사용자에 테스트할 사용자의 메일을 적어주고 다음으로 넘어간다.

  • 그리고 사용자 인증 정보로 들어가서 이름을 적고 승인된 리디렉션 URI를 설정해준다.
    승인된 리디렉션 URI는 프론트에서 구글 로그인을 한 뒤에 넘어갈 사이트를 적어준다. 본인은 프론트의 라우터로 넘어가서 프론트에서 인가 코드를 가져온 다음 백엔드로 값을 보내주는 형식을 사용했다.

  • 사용자 인증 정보까지 모두 설정을 했으니 이번엔 라이브러리로 넘어간다.

위 사진에 보이는 Google+ API를 눌러 사용을 눌러준다.
(본인은 이 작업을 하지 않아 시간을 꽤 소모했다..)


구글 클라우드 플랫폼에 앱 등록을 완료했으니 이제 본격적으로 코드를 짜보자.

OAuth 로그인 코드

프론트엔드

window.location.href ="https://accounts.google.com/o/oauth2/auth?" +
  "client_id={클라이언트 ID}&"+
  "redirect_uri={리디렉션 URI}&"+
  "response_type=token&"+
  "scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile";

우선 프론트에서 구글 로그인을 위한 버튼을 만들고 그 버튼을 눌렀을 때 위의 링크로 이동하도록 설정해준다.

  • client_id : google cloud platform > 사용자 인증 정보에 가면 아까 만든 클라이언트 id가 있다. 그것을 복사해서 붙여준다.
  • redirect_uri : 이것도 아까 적은 리디렉션 URI를 적어준다.
  • response_type : token을 받겠다고 적어주고
  • scope : 받아올 유저의 정보 범위를 적어준다.

리디렉션으로 넘어온 URI 코드

const parsedHash = new URLSearchParams(window.location.hash.substring(1));
const accessToken = parsedHash.get("access_token");

const { data } = await Api.post("oauth/google", { accessToken });

위의 코드를 이용해서 쿼리문으로 받아온 access_token 값을 뽑아오고 백엔드로 넘겨준다.

백엔드

const { accessToken } = req.body;

const { data } = await axios.get(
            `https://www.googleapis.com/oauth2/v1/userinfo?access_token=${accessToken}`
        );

백엔드에서는 프론트엔드에서 넘어온 accessToken값을 이용해서 구글 서버에 사용자의 정보를 요청한다.

정보를 받은 뒤에는 본인의 DB에 회원가입 혹은 로그인을 진행하고, JWT 토큰을 새로 발급해서 로그인을 진행해주면 끝이다!

본인은 DB에 없는 정보면 회원가입을, 있는 정보라면 로그인을 시켜주는 방식으로 진행했다.

이전부터 도전해보고 싶었던 방식이었는데 시간이 많이 걸리고 코딩을 완수하지 못해서 매번 문턱에서 멈췄었다..
막상 코드를 완성한 뒤에 포스팅을 하다보니 생각보다 간단했다..
코딩할때에는 시간이 많이 걸리고, 삽질도 많이 했는데 허무하기도 하지만 이번 기회에 제대로 기억하고 잊지말아야겠다.

profile
개발을 꾸준히 해보자
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 7월 6일

credential을 디코딩해서 구현하려고했는데 인증을 여러번 하니까 credential 정보는 넘어오지않더라구요 ㅠㅠ 그래서 검색하다가 올리신 포스팅을 보고 구글 api 조회를 한번더 태우니 제가 원하는 프로필 정보가 넘어오는군요 !! ㅠㅠ 도움이 많이됐습니당 감사합니다

답글 달기
comment-user-thumbnail
2023년 11월 5일

너무 많은 도움이 되었습니다!
궁금한 점이 있어 댓글을 남겨요
혹시 백엔드로 넘어가는 과정에서 백엔드에 필요한 다른 코드들이 있는지 궁금한데,,,
혹시 해당 코드들의 전체 코드를 깃헙 등을 통해 알 수 있을까요?

프로젝트 중 로그인/회원가입 구현을 하고 있는데 여러 파일들을 어떻게 연결해야하는지 잘 모르겠습니다ㅠ

답글 달기