코드 모델 사용

Google Identity Services 라이브러리를 사용하면 사용자가 브라우저 기반 팝업 또는 리디렉션 UX 흐름을 사용하여 Google에 승인 코드를 요청할 수 있습니다. 이렇게 하면 보안 OAuth 2.0 흐름이 시작되고 사용자 대신 Google API를 호출하는 데 사용되는 액세스 토큰이 생성됩니다.

OAuth 2.0 승인 코드 흐름 요약:

  • 브라우저에서 버튼 클릭과 같은 동작을 통해 Google 계정 소유자가 Google에 승인 코드를 요청합니다.
  • Google은 사용자 브라우저에서 실행되는 JavaScript 웹 앱의 콜백에 고유한 승인 코드를 전송하거나 브라우저 리디렉션을 사용하여 승인 코드 엔드포인트를 직접 호출하여 응답합니다.
  • 백엔드 플랫폼이 승인 코드 엔드포인트를 호스팅하고 코드를 수신합니다. 유효성 검사 후 이 코드는 Google의 토큰 엔드포인트에 대한 요청을 사용하여 사용자별 액세스 및 갱신 토큰으로 교환됩니다.
  • Google은 승인 코드를 검증하고, 요청이 보안 플랫폼에서 시작되었는지 확인하고, 액세스 및 새로고침 토큰을 발급하고, 플랫폼에서 호스팅하는 로그인 엔드포인트를 호출하여 토큰을 반환합니다.
  • 로그인 엔드포인트는 액세스 토큰과 갱신 토큰을 수신하고 나중에 사용할 수 있도록 갱신 토큰을 안전하게 저장합니다.

기본 요건

설정에 설명된 단계에 따라 OAuth 동의 화면을 구성하고, 클라이언트 ID를 가져오고, 클라이언트 라이브러리를 로드합니다.

코드 클라이언트 초기화

google.accounts.oauth2.initCodeClient() 메서드는 코드 클라이언트를 초기화합니다.

리디렉션 또는 팝업 모드 사용자 흐름을 사용하여 인증 코드를 공유할 수 있습니다. 리디렉션 모드에서는 서버에서 OAuth2 승인 엔드포인트를 호스팅하고 Google은 사용자 에이전트를 이 엔드포인트로 리디렉션하여 인증 코드를 URL 매개변수로 공유합니다. 팝업 모드의 경우 서버에 승인 코드를 전송하는 JavaScript 콜백 핸들러를 정의합니다. 팝업 모드를 사용하면 방문자가 사이트를 떠나지 않고도 원활한 사용자 환경을 제공할 수 있습니다.

다음을 위한 클라이언트를 초기화하려면 다음을 실행하세요.

  • UX 흐름을 리디렉션하고 ux_moderedirect로, redirect_uri 값을 플랫폼의 승인 코드 엔드포인트로 설정합니다. 이 값은 Google Cloud 콘솔에서 구성한 OAuth 2.0 클라이언트의 승인된 리디렉션 URI 중 하나와 정확히 일치해야 합니다. 또한 리디렉션 URI 유효성 검사 규칙을 준수해야 합니다.

  • 팝업 UX 흐름, ux_modepopup로 설정, callback 값을 플랫폼에 승인 코드를 전송하는 데 사용할 함수의 이름으로 설정 redirect_uri의 기본값은 initCodeClient을 호출하는 페이지의 출처입니다. 이 값은 나중에 인증 코드가 액세스 토큰 또는 갱신 토큰으로 교환될 때 흐름에서 사용됩니다. 예를 들어 https://www.example.com/index.htmlinitCodeClient를 호출하고 출처 https://www.example.comredirect_url의 값입니다.

CSRF 공격으로부터 보호

크로스 사이트 요청 위조 (CSRF) 공격을 방지하기 위해 리디렉션 및 팝업 모드 UX 흐름에 약간 다른 기술이 사용됩니다. 리디렉션 모드의 경우 OAuth 2.0 state 매개변수가 사용됩니다. state 매개변수 생성 및 검증에 관한 자세한 내용은 RFC6749 섹션 10.12 크로스 사이트 요청 위조를 참고하세요. 팝업 모드에서는 요청에 맞춤 HTTP 헤더를 추가한 다음 서버에서 예상 값 및 출처와 일치하는지 확인합니다.

UX 모드를 선택하여 승인 코드와 CSRF 처리를 보여주는 코드 스니펫을 확인하세요.

리디렉션 모드

Google이 사용자의 브라우저를 인증 엔드포인트로 리디렉션하여 인증 코드를 URL 매개변수로 공유하는 클라이언트를 초기화합니다.

const client = google.accounts.oauth2.initCodeClient({   client_id: 'YOUR_CLIENT_ID',   scope: 'https://www.googleapis.com/auth/calendar.readonly',   ux_mode: 'redirect',   redirect_uri: 'https://oauth2.example.com/code',   state: 'YOUR_BINDING_VALUE' }); 

사용자가 팝업 대화상자에서 승인 흐름을 시작하는 클라이언트를 초기화합니다. 동의 후 Google은 콜백 함수를 사용하여 사용자 브라우저에 승인 코드를 반환합니다. JS 콜백 핸들러의 POST 요청은 인증 코드를 백엔드 서버의 엔드포인트로 전달합니다. 여기서 인증 코드는 먼저 확인된 후 나머지 OAuth 흐름이 완료됩니다.

const client = google.accounts.oauth2.initCodeClient({   client_id: 'YOUR_CLIENT_ID',   scope: 'https://www.googleapis.com/auth/calendar.readonly',   ux_mode: 'popup',   callback: (response) => {     const xhr = new XMLHttpRequest();     xhr.open('POST', "https://oauth2.example.com/code", true);     xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');     // Set custom header for CRSF     xhr.setRequestHeader('X-Requested-With', 'XmlHttpRequest');     xhr.onload = function() {       console.log('Auth code response: ' + xhr.responseText);     };     xhr.send('code=' + response.code);   }, }); 

OAuth 2.0 코드 흐름 트리거

코드 클라이언트의 requestCode() 메서드를 호출하여 사용자 흐름을 트리거합니다.

<button onclick="client.requestCode();">Authorize with Google</button> 

이렇게 하면 사용자가 Google 계정에 로그인하고 리디렉션 엔드포인트나 콜백 핸들러에 승인 코드를 반환하기 전에 개별 범위를 공유하는 데 동의해야 합니다.

인증 코드 처리

Google은 사용자별 고유 승인 코드를 생성하며, 이 코드는 백엔드 서버에서 수신하고 확인합니다.

팝업 모드의 경우 callback로 지정된 핸들러가 사용자 브라우저에서 실행되어 승인 코드를 플랫폼에서 호스팅하는 엔드포인트로 전달합니다.

리디렉션 모드의 경우 redirect_uri로 지정된 엔드포인트로 GET 요청이 전송되어 URL code 매개변수에서 승인 코드를 공유합니다. 승인 코드를 받으려면 다음 단계를 따르세요.

  • 기존 구현이 없는 경우 새 승인 엔드포인트만들거나

  • GET 요청과 URL 매개변수를 수락하도록 기존 엔드포인트를 업데이트합니다. 이전에는 페이로드에 승인 코드 값이 있는 PUT 요청이 사용되었습니다.

승인 엔드포인트

승인 코드 엔드포인트는 다음 URL 쿼리 문자열 매개변수를 사용하여 GET 요청을 처리해야 합니다.

이름
authuser 사용자 로그인 인증 요청
코드 Google에서 생성한 OAuth2 승인 코드
HD 사용자 계정의 호스팅 도메인
프롬프트 사용자 동의 대화상자
범위 승인할 하나 이상의 OAuth2 범위의 공백으로 구분된 목록
CRSF 상태 변수

auth-code라는 엔드포인트에 대한 URL 매개변수가 포함된 GET 요청으로, example.com에서 호스팅됩니다.

Request URL: https://www.example.com/auth-code?state=42a7bd822fe32cc56&code=4/0AX4XfWiAvnXLqxlckFUVao8j0zvZUJ06AMgr-n0vSPotHWcn9p-zHCjqwr47KHS_vDvu8w&scope=email%20profile%20https://www.googleapis.com/auth/calendar.readonly%20https://www.googleapis.com/auth/photoslibrary.readonly%20https://www.googleapis.com/auth/contacts.readonly%20openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&authuser=0&hd=example.com&prompt=consent 

이전 JavaScript 라이브러리 또는 Google OAuth 2.0 엔드포인트에 대한 직접 호출에 의해 승인 코드 흐름이 시작되면 POST 요청이 사용됩니다.

HTTP 요청 본문에 승인 코드가 페이로드로 포함된 POST 요청의 예:

Request URL: https://www.example.com/auth-code Request Payload: 4/0AX4XfWhll-BMV82wi4YwbrSaTPaRpUGpKqJ4zBxQldU\_70cnIdh-GJOBZlyHU3MNcz4qaw 

요청 유효성 확인

서버에서 다음을 수행하여 CSRF 공격을 방지하세요.

리디렉션 모드의 경우 state 매개변수의 값을 확인합니다.

X-Requested-With: XmlHttpRequest 헤더가 팝업 모드로 설정되어 있는지 확인합니다.

그런 다음 먼저 인증 코드 요청을 성공적으로 확인한 경우에만 Google에서 새로고침 및 액세스 토큰을 가져와야 합니다.

액세스 토큰 및 갱신 토큰 가져오기

백엔드 플랫폼이 Google로부터 승인 코드를 수신하고 요청을 확인한 후 승인 코드를 사용하여 Google로부터 액세스 토큰과 갱신 토큰을 획득하여 API를 호출합니다.

웹 서버 애플리케이션에 OAuth 2.0 사용 가이드의 5단계: 갱신 및 액세스 토큰을 위해 승인 코드 교환부터 시작하는 안내를 따르세요.

토큰 관리

플랫폼에서 갱신 토큰을 안전하게 저장합니다. 사용자 계정이 삭제되거나 google.accounts.oauth2.revoke에 의해 또는 https://myaccount.google.com/permissions에서 직접 사용자 동의가 취소되면 저장된 갱신 토큰을 삭제합니다.

원하는 경우 RISC를 사용하여 크로스 계정 보호로 사용자 계정을 보호할 수 있습니다.

일반적으로 백엔드 플랫폼은 액세스 토큰을 사용하여 Google API를 호출합니다. 웹 앱이 사용자의 브라우저에서 Google API를 직접 호출하는 경우 액세스 토큰을 웹 애플리케이션과 공유하는 방법을 구현해야 합니다. 이는 이 가이드의 범위를 벗어납니다. 이 접근 방식을 따르고 JavaScript용 Google API 클라이언트 라이브러리를 사용하는 경우 gapi.client.SetToken()를 사용하여 액세스 토큰을 브라우저 메모리에 일시적으로 저장하고 라이브러리가 Google API를 호출할 수 있도록 합니다.