Google Identity Services 라이브러리를 사용하면 사용자가 브라우저 기반 팝업 또는 리디렉션 UX 흐름을 사용하여 Google에서 승인 코드를 요청할 수 있습니다. 그러면 안전한 OAuth 2.0 흐름이 시작되고 사용자를 대신하여 Google API를 호출하는 데 사용되는 액세스 토큰이 생성됩니다.
OAuth 2.0 승인 코드 흐름 요약:
- Google 계정 소유자가 브라우저에서 버튼 클릭과 같은 동작으로 Google에 승인 코드를 요청합니다.
- Google은 사용자의 브라우저에서 실행 중인 JavaScript 웹 앱의 콜백에 고유한 승인 코드를 전송하거나 브라우저 리디렉션을 사용하여 승인 코드 엔드포인트를 직접 호출하여 응답합니다.
- 백엔드 플랫폼은 승인 코드 엔드포인트를 호스팅하고 코드를 수신합니다. 유효성 검사 후 이 코드는 Google의 토큰 엔드포인트에 대한 요청을 사용하여 사용자별 액세스 토큰 및 갱신 토큰으로 교환됩니다.
- Google은 승인 코드를 확인하고, 요청이 보안 플랫폼에서 발생했는지 확인하고, 액세스 및 갱신 토큰을 발급하고, 플랫폼에서 호스팅하는 로그인 엔드포인트를 호출하여 토큰을 반환합니다.
- 로그인 엔드포인트는 액세스 토큰과 갱신 토큰을 수신하여 나중에 사용할 수 있도록 갱신 토큰을 안전하게 저장합니다.
기본 요건
설정에 설명된 단계에 따라 OAuth 동의 화면을 구성하고, 클라이언트 ID를 가져오고, 클라이언트 라이브러리를 로드합니다.
Code 클라이언트 초기화
google.accounts.oauth2.initCodeClient()
메서드는 코드 클라이언트를 초기화합니다.
팝업 또는 리디렉션 모드
리디렉션 또는 팝업 모드 사용자 흐름을 사용하여 인증 코드를 공유할 수 있습니다. 리디렉션 모드를 사용하면 서버에서 OAuth2 승인 엔드포인트를 호스팅하고 Google에서 사용자 에이전트를 이 엔드포인트로 리디렉션하여 인증 코드를 URL 매개변수로 공유합니다. 팝업 모드의 경우 승인 코드를 서버로 전송하는 JavaScript 콜백 핸들러를 정의합니다. 팝업 모드를 사용하면 방문자가 사이트를 나가지 않아도 원활한 사용자 환경을 제공할 수 있습니다.
다음의 클라이언트를 초기화하려면 다음을 실행합니다.
UX 흐름을 리디렉션하고
ux_mode
를redirect
로,redirect_uri
값을 플랫폼의 승인 코드 엔드포인트로 설정합니다. 이 값은 API Console에서 구성한 OAuth 2.0 클라이언트에 승인된 리디렉션 URI 중 하나와 정확하게 일치해야 합니다. 또한 리디렉션 URI 유효성 검사 규칙을 준수해야 합니다.팝업 UX 흐름을 실행하고
ux_mode
를popup
로 설정하고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
요청을 처리해야 합니다.
이름 | 값 |
---|---|
authuser | 사용자 로그인 인증 요청 |
코드 | Google에서 생성한 OAuth2 승인 코드 |
HD | 사용자 계정의 호스팅된 도메인 |
프롬프트 | 사용자 동의 대화상자 |
범위 | 승인할 OAuth2 범위 1개 이상의 공백으로 구분된 목록 |
주 | 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
이전 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를 호출하도록 사용 설정합니다.