JavaScript/NextJS

[NextJS] OAuth 2.0 구글 로그인 API 적용하기

제이널 2023. 6. 5. 18:39

배경

최근 소셜(간편) 로그인은 대부분의 서비스의 필수 기능이 되었습니다.  회원가입 절차가 간단해지고, 사용자가 서비스에 접근하기 쉬워지기 때문에 유저 확보의 장점만 보더라도 개발하지 않을 이유가 없게 된 것이죠.

 

이러한 로그인은 SSO(Single Sign on)라는 이름으로 불리기도 하는데요, 구글을 예로 들면, 구글 로그인을 한 번 하면, 구글의 여러 서비스에서 따로 로그인 할 필요 없이 구글의 서비스를 이용할 수 있다는 점을 들 수 있습니다. 이러한 로그인은 구글 뿐만 아니라, 페이스북, 네이버, 카카오톡 등의 서비스에서 제공하고 있습니다.

 

SSO는 인증(Authentication)인가(Authorization)와 관련이 있는데요, 인증은 로그인과 같이 사용자를 인증하는 과정이며, 인가는 어느 행위를 할 때 인증된 정보를 통해 그 행위의 권한을 검증하는 과정을 뜻하며, 이러한 과정을 통해 한 번의 로그인으로 여러 서비스를 이용할 수 있게 되는 것입니다.


OAuth?

OAuth(Open Authorization)는 인증 및 인가 프로토콜로써, 애플리케이션에서 서드 파티 애플리케이션에 사용자 데이터에 대한 안전한 접근 권한을 부여하기 위해 사용됩니다. OAuth는 사용자가 자신의 계정 정보를 공유하지 않고도 다른 애플리케이션에 접근할 수 있도록 허용합니다.

 

구글을 예로 든 OAuth의 절차는 대략적으로 아래와 같습니다.

  1. 사용자가 구글 계정 연동 요청
  2. 사용자가 구글 로그인 화면에서 로그인
  3. 구글 인가 서버가 서비스의 Redirect URI로 토큰 전달
  4. 서비스의 백엔드는 토큰을 사용해 사용자 정보 조회
  5. 조회된 사용자 정보를 DB에 저장하고, 회원가입 처리

목차

1. 구글 개발자 설정

2. 개발


1. 구글 개발자 설정

 

구글 클라우드 콘솔에 접속해서 OAuth 동의 화면을 만듭니다.

https://console.cloud.google.com/apis/credentials/consent

 

 

'OAuth 동의 화면'에서 아래 항목을 입력하고 '저장 후 계속'을 클릭합니다.

 

  1. 앱 이름
  2. 사용자 지원 이메일
  3. 앱 로고
  4. 개발자 연락처 정보

 

'범위'에선 서비스에서 가져올 사용자 정보 범위를 추가합니다.

 

 

'테스트 사용자'에선 구글 로그인을 사용할 이메일을 추가합니다.

누구나 사용하기 위해선 별도 애플리케이션 심사가 필요합니다.

 

 

이제 대시보드에서 '앱 게시'를 클릭합니다.

 

다음으로 '사용자 인증 정보' 메뉴로 이동합니다.

 

 

'사용자 인증 정보 만들기' > 'OAuth 클라이언트 ID 만들기'를 클릭한 후, 애플리케이션 유형을 '웹 애플리케이션'으로 설정합니다.

 

 

승인된 자바스크립트 원본, 승인된 리디렉션 URI를 입력합니다.

승인된 자바스크립트 원본은 frontend에서 구글 로그인 시 구글이 승인해줄 도메인을 입력하고, 승인된 리디렉션 URI에는 로그인 완료 후에 이동될 페이지 URI를 입력해주시면 됩니다.

 

  • 클라이언트 ID와 클라이언트 보안 비밀번호는 개발에 사용될 예정이니, 환경변수에 추가해두는 것이 좋습니다.

 

이제 구글 개발자 콘솔에서의 준비는 완료되었습니다.


2. 개발

 

먼저 구글 로그인 버튼을 누르면 사용자가 로그인을 할 수 있도록 팝업을 띄우거나 페이지를 이동시켜주면 됩니다.

 

function clickLoginGoogle() {
    const url =
      `https://accounts.google.com/o/oauth2/v2/auth?` +
      `client_id=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}&` +
      `redirect_uri=${process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URL}&` +
      `response_type=code&` +
      `scope=email profile&` +
      `state=YOUR_PARAMETER`;
    location.href = url;
  }
  • client_id: 앱의 클라이언트 아이디를 입력합니다.
  • redirect_uri: 개발자 콘솔에 입력했던 URI를 입력합니다.
  • response_type: 응답을 무엇으로 받을지 설정합니다. 이 예제에선 인가 코드를 받도록 설정되어 있습니다.
  • scope: 조회 권한 범위를 입력하며, 띄어쓰기로 구분합니다.
  • state(선택): redirect_uri에 파라미터 값을 전달해줄 수 있습니다. Object 타입의 경우 stringify를 사용해 string 형태로 변환해서 보내야 합니다.

 

이후에 로그인을 하면 redirect_uri로 페이지가 이동되며, query parameter에서 code 값을 사용해 유저의 정보를 조회할 수 있습니다.

 

let url =
  'https://oauth2.googleapis.com/token?' +
  `code=${code}&` +
  `client_id=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}&` +
  `client_secret=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET}&` +
  `redirect_uri=${process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI}&` +
  `grant_type=authorization_code`;

// 인가 코드를 사용해 액세스 토큰 조회
const { data } = await axios.post(url);
const { access_token } = data;
console.log(access_token);

// 액세스 토큰을 사용해 사용자 정보 조회
url = `https://www.googleapis.com/oauth2/v2/userinfo?access_token=${access_token}`;
const { data: userInfo } = await axios.get(url, {
  headers: {
    authorization: `Bearer ${access_token}`,
  },
});
console.log(userInfo);

 

인가 코드를 백엔드로 전송해서 사용자 정보를 사용해 회원가입 처리를 할 수도 있을 것입니다.


참고