코드 모델 사용

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

OAuth 2.0 승인 코드 흐름 요약:

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

코드 클라이언트 초기화

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

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

다음에 대한 클라이언트를 초기화하는 방법은 다음과 같습니다.

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

  • 팝업 UX 흐름에서 ux_modepopup로 설정하고 callback 값을 플랫폼에 승인 코드를 전송하는 데 사용할 함수 이름으로 설정합니다.

CSRF 공격 방지

CSRF (Cross-Site-Request-Forgery) 공격을 방지하기 위해 리디렉션 및 팝업 모드 UX 흐름에 다양한 기술을 사용합니다. 리디렉션 모드에서는 OAuth 2.0 state 매개변수가 사용됩니다. state 매개변수 생성 및 유효성 검사에 관한 자세한 내용은 RFC6749 섹션 10.12 교차 사이트 요청 위조를 참고하세요. 팝업 모드를 사용하면 요청에 커스텀 HTTP 헤더를 추가한 다음 서버에서 예상 값 및 출처와 일치하는지 확인합니다.

인증 코드 및 CSRF 처리를 보여주는 코드 스니펫을 보려면 UX 모드를 선택합니다.

리디렉션 모드

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

const client = google.accounts.oauth2.initCodeClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'redirect',
  redirect_uri: "https://your.domain/code_callback_endpoint",
  state: "YOUR_BINDING_VALUE"
});

사용자의 브라우저가 Google로부터 인증 코드를 받아 서버로 전송하는 클라이언트를 초기화합니다.

const client = google.accounts.oauth2.initCodeClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  ux_mode: 'popup',
  callback: (response) => {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', code_receiver_uri, 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_url 요청이 지정한 엔드포인트로 GET 요청이 전송되어 URL 코드 매개변수의 승인 코드를 공유합니다. 승인 코드를 받으려면 다음 안내를 따르세요.

  • 기존 구현이 없는 경우 새 승인 엔드포인트만듭니다.

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

승인 엔드포인트

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

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

example.com에서 호스팅하고 auth-code라는 엔드포인트에 대한 URL 매개변수가 포함된 GET 요청의 예:

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

이전 자바스크립트 라이브러리 또는 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를 직접 호출하는 경우 웹 애플리케이션과 액세스 토큰을 공유하는 방법을 구현해야 합니다. 이는 이 가이드의 범위를 벗어나는 내용입니다. 이 방법을 따르고 자바스크립트용 Google API 클라이언트 라이브러리를 사용할 때는 gapi.client.SetToken()를 사용하여 브라우저 메모리에 액세스 토큰을 일시적으로 저장하고 라이브러리가 Google API를 호출하도록 사용 설정합니다.