코드 모델 사용

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

OAuth 2.0 승인 코드 흐름 요약:

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

코드 클라이언트 초기화

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

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

다음에 대한 클라이언트를 초기화하려면 다음 안내를 따르세요.

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

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

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_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으로 지정된 핸들러가 승인 코드를 플랫폼에서 호스팅하는 엔드포인트로 전달합니다.

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

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

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

승인 엔드포인트

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

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

auth-code라는 엔드포인트에 대한 URL 매개변수를 포함하고 example.com에서 호스팅하는 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

승인 코드 흐름이 이전 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를 호출하도록 사용 설정합니다.