OAuth 2.0 для клиентских веб-приложений

В этом документе объясняется, как реализовать авторизацию OAuth 2.0 для доступа к API Google из веб-приложения JavaScript. OAuth 2.0 позволяет пользователям обмениваться определенными данными с приложением, сохраняя при этом свои имена пользователей, пароли и другую информацию в тайне. Например, приложение может использовать OAuth 2.0 для получения разрешения от пользователей на хранение файлов на их Google Дисках.

Этот поток OAuth 2.0 называется неявным потоком предоставления . Он предназначен для приложений, которые обращаются к API только тогда, когда пользователь присутствует в приложении. Эти приложения не могут хранить конфиденциальную информацию.

В этом потоке ваше приложение открывает URL-адрес Google, который использует параметры запроса для идентификации вашего приложения и типа доступа к API, который требуется приложению. Вы можете открыть URL-адрес в текущем окне браузера или во всплывающем окне. Пользователь может пройти аутентификацию в Google и предоставить запрошенные разрешения. Затем Google перенаправляет пользователя обратно в ваше приложение. Перенаправление включает токен доступа, который ваше приложение проверяет, а затем использует для выполнения запросов API.

Предпосылки

Включите API для вашего проекта

Любое приложение, которое вызывает API Google, должно включить эти API в API Console.

Чтобы включить API для вашего проекта:

  1. Open the API Library в Google API Console.
  2. If prompted, select a project, or create a new one.
  3. В API Library перечислены все доступные API, сгруппированные по семейству продуктов и популярности. Если API, который вы хотите включить, не отображается в списке, используйте поиск, чтобы найти его, или нажмите « Просмотреть все » в семействе продуктов, к которому он принадлежит.
  4. Выберите API, который вы хотите включить, затем нажмите кнопку « Включить ».
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Создать учетные данные для авторизации

Любое приложение, использующее OAuth 2.0 для доступа к API Google, должно иметь учетные данные авторизации, которые идентифицируют приложение на сервере Google OAuth 2.0. Следующие шаги объясняют, как создать учетные данные для вашего проекта. Затем ваши приложения могут использовать учетные данные для доступа к API, которые вы включили для этого проекта.

  1. Go to the Credentials page.
  2. Щелкните Создать учетные данные > Идентификатор клиента OAuth .
  3. Выберите тип веб-приложения .
  4. Заполните форму. Приложения, использующие JavaScript для авторизованных запросов API Google, должны указывать авторизованные источники JavaScript . Источники определяют домены, из которых ваше приложение может отправлять запросы на сервер OAuth 2.0. Эти источники должны соответствовать правилам проверки Google .

Определение областей доступа

Области позволяют вашему приложению запрашивать доступ только к тем ресурсам, которые ему необходимы, а также позволяют пользователям контролировать объем доступа, который они предоставляют вашему приложению. Таким образом, может существовать обратная зависимость между количеством запрошенных областей действия и вероятностью получения согласия пользователя.

Прежде чем приступить к реализации авторизации OAuth 2.0, мы рекомендуем определить области, для доступа к которым вашему приложению потребуется разрешение.

Документ OAuth 2.0 API Scopes содержит полный список областей, которые вы можете использовать для доступа к Google API.

Получение токенов доступа OAuth 2.0

Следующие шаги показывают, как ваше приложение взаимодействует с сервером Google OAuth 2.0, чтобы получить согласие пользователя на выполнение запроса API от имени пользователя. Ваше приложение должно получить это согласие, прежде чем оно сможет выполнять запрос API Google, требующий авторизации пользователя.

Шаг 1. Настройте клиентский объект

Если вы используете клиентскую библиотеку API Google для JavaScript для обработки потока OAuth 2.0, первым шагом будет настройка объектов gapi.auth2 и gapi.client . Эти объекты позволяют вашему приложению получать авторизацию пользователя и выполнять авторизованные запросы API.

Объект клиента идентифицирует области, к которым ваше приложение запрашивает разрешение на доступ. Эти значения сообщают экран согласия, который Google показывает пользователю.

JS-клиентская библиотека

Клиентская библиотека JavaScript упрощает многие аспекты процесса авторизации:

  1. Он создает URL-адрес перенаправления для сервера авторизации Google и предоставляет метод для направления пользователя на этот URL-адрес.
  2. Он обрабатывает перенаправление с этого сервера обратно в ваше приложение.
  3. Он проверяет токен доступа, возвращенный сервером авторизации.
  4. Он хранит токен доступа, который сервер авторизации отправляет вашему приложению, и извлекает его, когда ваше приложение впоследствии выполняет авторизованные вызовы API.

Приведенный ниже фрагмент кода является выдержкой из полного примера , показанного далее в этом документе. Этот код инициализирует объект gapi.client , который впоследствии будет использоваться вашим приложением для вызовов API. При создании этого объекта также инициализируется объект gapi.auth2 , который ваше приложение использует для проверки и мониторинга статуса авторизации пользователя.

При вызове gapi.client.init указываются следующие поля:

  • Значения apiKey и clientId указывают учетные данные авторизации вашего приложения. Как обсуждалось в разделе о создании учетных данных для авторизации , эти значения можно получить в API Console. Обратите внимание, что clientId требуется, если ваше приложение отправляет авторизованные запросы API. Приложения, которые делают только неавторизованные запросы, могут просто указать ключ API.
  • Поле scope определяет разделенный пробелами список областей доступа , соответствующих ресурсам, к которым ваше приложение может получить доступ от имени пользователя. Эти значения сообщают экран согласия, который Google показывает пользователю.

    Мы рекомендуем, чтобы ваше приложение запрашивало доступ к областям авторизации в контексте, когда это возможно. Запрашивая доступ к пользовательским данным в контексте с помощью инкрементной авторизации , вы помогаете пользователям легче понять, почему вашему приложению нужен запрашиваемый доступ.

  • Поле discoveryDocs определяет список документов API Discovery , которые использует ваше приложение. Документ Discovery описывает поверхность API, включая его схемы ресурсов, и клиентская библиотека JavaScript использует эту информацию для создания методов, которые могут использовать приложения. В этом примере код извлекает документ обнаружения для версии 3 API Google Диска.

После завершения вызова gapi.client.init код устанавливает переменную GoogleAuth для идентификации объекта Google Auth. Наконец, код устанавливает прослушиватель, который вызывает функцию при изменении состояния входа пользователя. (Эта функция не определена во фрагменте.)

var GoogleAuth; // Google Auth object.
function initClient() {
  gapi.client.init({
      'apiKey': 'YOUR_API_KEY',
      'clientId': 'YOUR_CLIENT_ID',
      'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
      'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
  });
}

Конечные точки OAuth 2.0

Если вы напрямую обращаетесь к конечным точкам OAuth 2.0, вы можете перейти к следующему шагу.

Шаг 2. Перенаправление на сервер Google OAuth 2.0

Чтобы запросить разрешение на доступ к данным пользователя, перенаправьте пользователя на сервер Google OAuth 2.0.

JS-клиентская библиотека

Вызовите метод GoogleAuth.signIn() , чтобы направить пользователя на сервер авторизации Google.

GoogleAuth.signIn();

На практике ваше приложение может установить логическое значение, чтобы определить, следует ли вызывать метод signIn() перед попыткой выполнения вызова API.

Фрагмент кода ниже демонстрирует, как можно инициировать процесс авторизации пользователя. Обратите внимание на следующие моменты, касающиеся фрагмента:

  • Объект GoogleAuth , указанный в коде, совпадает с глобальной переменной, определенной во фрагменте кода на шаге 1 .

  • Функция updateSigninStatus — это прослушиватель, который отслеживает изменения статуса авторизации пользователя. Его роль в качестве слушателя также была определена во фрагменте кода на шаге 1:
    GoogleAuth.isSignedIn.listen(updateSigninStatus);
    .
  • Фрагмент определяет две дополнительные глобальные переменные:

    • isAuthorized — это логическая переменная, указывающая, вошел ли пользователь уже в систему. Это значение можно установить при загрузке приложения и обновить, если пользователь входит в приложение или выходит из него.

      В этом фрагменте функция sendAuthorizedApiRequest проверяет значение переменной, чтобы определить, должно ли приложение выполнить запрос API, требующий авторизации, или предложить пользователю авторизовать приложение.

    • currentApiRequest — это объект, в котором хранятся сведения о последнем запросе API, предпринятом пользователем. Значение объекта устанавливается, когда приложение вызывает функцию sendAuthorizedApiRequest .

      Если пользователь авторизовал приложение, запрос выполняется сразу. В противном случае функция перенаправляет пользователя для входа. После входа пользователя функция updateSignInStatus вызывает sendAuthorizedApiRequest , передавая тот же запрос, который был предпринят до запуска потока авторизации.

var isAuthorized;
var currentApiRequest;

/**
 * Store the request details. Then check to determine whether the user
 * has authorized the application.
 *   - If the user has granted access, make the API request.
 *   - If the user has not granted access, initiate the sign-in flow.
 */
function sendAuthorizedApiRequest(requestDetails) {
  currentApiRequest = requestDetails;
  if (isAuthorized) {
    // Make API request
    // gapi.client.request(requestDetails)

    // Reset currentApiRequest variable.
    currentApiRequest = {};
  } else {
    GoogleAuth.signIn();
  }
}

/**
 * Listener called when user completes auth flow. If the currentApiRequest
 * variable is set, then the user was prompted to authorize the application
 * before the request executed. In that case, proceed with that API request.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    isAuthorized = true;
    if (currentApiRequest) {
      sendAuthorizedApiRequest(currentApiRequest);
    }
  } else {
    isAuthorized = false;
  }
}

Конечные точки OAuth 2.0

Создайте URL-адрес для запроса доступа с конечной точки Google OAuth 2.0 по адресу https://accounts.google.com/o/oauth2/v2/auth . Эта конечная точка доступна через HTTPS; обычные HTTP-соединения отклоняются.

Сервер авторизации Google поддерживает следующие параметры строки запроса для приложений веб-сервера:

Параметры
client_id Необходимый

Идентификатор клиента для вашего приложения. Вы можете найти это значение в API ConsoleCredentials page.

redirect_uri Необходимый

Определяет, куда сервер API перенаправляет пользователя после того, как пользователь завершит процесс авторизации. Значение должно точно совпадать с одним из авторизованных URI перенаправления для клиента OAuth 2.0, который вы настроили в API ConsoleCredentials pageвашего клиента. Если это значение не соответствует авторизованному URI перенаправления для предоставленного client_id , вы получите ошибку redirect_uri_mismatch .

Обратите внимание, что схема http или https , регистр и завершающая косая черта (' / ') должны совпадать.

response_type Необходимый

Приложения JavaScript должны установить значение параметра token . Это значение указывает серверу авторизации Google возвращать токен доступа в виде пары name=value в идентификаторе фрагмента URI ( # ), на который перенаправляется пользователь после завершения процесса авторизации.

scope Необходимый

Разделенный пробелами список областей, определяющих ресурсы, к которым ваше приложение может получить доступ от имени пользователя. Эти значения сообщают экран согласия, который Google показывает пользователю.

Области позволяют вашему приложению запрашивать доступ только к тем ресурсам, которые ему необходимы, а также позволяют пользователям контролировать объем доступа, который они предоставляют вашему приложению. Таким образом, существует обратная зависимость между количеством запрошенных областей действия и вероятностью получения согласия пользователя.

Мы рекомендуем, чтобы ваше приложение запрашивало доступ к областям авторизации в контексте, когда это возможно. Запрашивая доступ к пользовательским данным в контексте с помощью инкрементной авторизации , вы помогаете пользователям легче понять, почему вашему приложению нужен запрашиваемый доступ.

state рекомендуемые

Задает любое строковое значение, которое ваше приложение использует для поддержания состояния между вашим запросом авторизации и ответом сервера авторизации. Сервер возвращает точное значение, которое вы отправляете в виде пары name=value в идентификаторе фрагмента URL-адреса ( # ) redirect_uri после того, как пользователь соглашается или отклоняет запрос доступа вашего приложения.

Вы можете использовать этот параметр для нескольких целей, таких как направление пользователя к правильному ресурсу в вашем приложении, отправка одноразовых номеров и предотвращение подделки межсайтовых запросов. Поскольку ваш redirect_uri можно угадать, использование значения state может повысить вашу уверенность в том, что входящее соединение является результатом запроса аутентификации. Если вы создаете случайную строку или кодируете хэш файла cookie или другое значение, фиксирующее состояние клиента, вы можете проверить ответ, чтобы дополнительно убедиться, что запрос и ответ исходят из одного и того же браузера, обеспечивая защиту от атак, таких как межсайтовые атаки. запросить подделку. См. документацию OpenID Connect для примера того, как создать и подтвердить токен state .

include_granted_scopes Необязательный

Позволяет приложениям использовать добавочную авторизацию для запроса доступа к дополнительным областям в контексте. Если вы установите для этого параметра значение true и запрос на авторизацию будет предоставлен, то новый токен доступа также будет охватывать все области, к которым пользователь ранее предоставил доступ приложению. Примеры см. в разделе инкрементной авторизации .

login_hint Необязательный

Если ваше приложение знает, какой пользователь пытается пройти аутентификацию, оно может использовать этот параметр, чтобы предоставить подсказку серверу аутентификации Google. Сервер использует подсказку, чтобы упростить процесс входа в систему, предварительно заполнив поле электронной почты в форме входа или выбрав соответствующий сеанс с несколькими входами.

Задайте в качестве значения параметра адрес электронной почты или sub идентификатор, который эквивалентен идентификатору Google ID пользователя.

prompt Необязательный

Разделенный пробелами и чувствительный к регистру список подсказок для представления пользователя. Если вы не укажете этот параметр, пользователю будет предложено только в первый раз, когда ваш проект запрашивает доступ. Дополнительные сведения см. в разделе Запрос повторного согласия .

Возможные значения:

none Не отображать никаких экранов аутентификации или согласия. Не должно быть указано с другими значениями.
consent Запрашивать у пользователя согласие.
select_account Предложите пользователю выбрать учетную запись.

Пример перенаправления на сервер авторизации Google

Ниже показан пример URL-адреса с разрывами строк и пробелами для удобства чтения.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

После создания URL-адреса запроса перенаправьте на него пользователя.

Пример кода JavaScript

В следующем фрагменте кода JavaScript показано, как инициировать процесс авторизации в JavaScript без использования клиентской библиотеки API Google для JavaScript. Поскольку эта конечная точка OAuth 2.0 не поддерживает совместное использование ресурсов между источниками (CORS), фрагмент кода создает форму, которая открывает запрос к этой конечной точке.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

Шаг 3. Google запрашивает у пользователя согласие

На этом шаге пользователь решает, предоставлять ли вашему приложению запрошенный доступ. На этом этапе Google отображает окно согласия, в котором отображается имя вашего приложения и службы API Google, для доступа к которым запрашивается разрешение с учетными данными пользователя, а также сводка областей доступа, которые должны быть предоставлены. Затем пользователь может дать согласие на предоставление доступа к одной или нескольким областям, запрошенным вашим приложением, или отклонить запрос.

Вашему приложению не нужно ничего делать на этом этапе, так как оно ожидает ответа от сервера Google OAuth 2.0, указывающего, был ли предоставлен какой-либо доступ. Этот ответ объясняется в следующем шаге.

Ошибки

Запросы к конечной точке авторизации OAuth 2.0 Google могут отображать сообщения об ошибках вместо ожидаемых потоков аутентификации и авторизации. Распространенные коды ошибок и предлагаемые решения перечислены ниже.

admin_policy_enforced

Аккаунт Google не может авторизовать одну или несколько запрошенных областей из-за правил администратора Google Workspace. Дополнительную информацию о том, как администратор может ограничить доступ ко всем областям или конфиденциальным и ограниченным областям, см. в справочной статье для администраторов Google Workspace Контролируйте, какие сторонние и внутренние приложения получают доступ к данным Google Workspace, пока доступ явно не предоставлен вашему идентификатору клиента OAuth.

disallowed_useragent

Конечная точка авторизации отображается внутри встроенного пользовательского агента, запрещенного политиками Google OAuth 2.0 .

Андроид

Разработчики Android могут столкнуться с этим сообщением об ошибке при открытии запросов авторизации вandroid.webkit.WebView . Вместо этого разработчикам следует использовать библиотеки Android, такие как Google Sign-In для Android или AppAuth OpenID Foundation для Android .

Веб-разработчики могут столкнуться с этой ошибкой, когда приложение Android открывает общую веб-ссылку во встроенном пользовательском агенте, а пользователь переходит к конечной точке авторизации Google OAuth 2.0 с вашего сайта. Разработчики должны разрешать открытие общих ссылок в обработчике ссылок по умолчанию операционной системы, который включает в себя как обработчики ссылок приложений Android , так и приложение браузера по умолчанию. Библиотека пользовательских вкладок Android также является поддерживаемым вариантом.

iOS

Разработчики iOS и macOS могут столкнуться с этой ошибкой при открытии запросов авторизации вWKWebView . Вместо этого разработчикам следует использовать библиотеки iOS, такие как Google Sign-In для iOS или AppAuth OpenID Foundation для iOS .

Веб-разработчики могут столкнуться с этой ошибкой, когда приложение iOS или macOS открывает общую веб-ссылку во встроенном пользовательском агенте, и пользователь переходит к конечной точке авторизации OAuth 2.0 Google с вашего сайта. Разработчики должны разрешить открытие общих ссылок в обработчике ссылок по умолчанию операционной системы, который включает в себя как обработчики универсальных ссылок , так и приложение браузера по умолчанию. БиблиотекаSFSafariViewController также является поддерживаемым вариантом.

org_internal

Идентификатор клиента OAuth в запросе является частью проекта, ограничивающего доступ к аккаунтам Google в определенной организации Google Cloud . Дополнительные сведения об этом параметре конфигурации см. в разделе « Тип пользователя» справочной статьи «Настройка экрана согласия OAuth».

origin_mismatch

Схема, домен и/или порт JavaScript, от которого исходит запрос на авторизацию, могут не совпадать с авторизованным URI источника JavaScript, зарегистрированным для идентификатора клиента OAuth. Просмотрите авторизованные источники JavaScript в Google API ConsoleCredentials page.

redirect_uri_mismatch

redirect_uri , переданный в запросе авторизации, не соответствует авторизованному URI перенаправления для идентификатора клиента OAuth. Просмотрите разрешенные URI перенаправления в Google API Console Credentials page.

Схема, домен и/или порт JavaScript, от которого исходит запрос на авторизацию, могут не совпадать с авторизованным URI источника JavaScript, зарегистрированным для идентификатора клиента OAuth. Просмотрите авторизованные источники JavaScript в Google API Console Credentials page.

Шаг 4. Обработайте ответ сервера OAuth 2.0

JS-клиентская библиотека

Клиентская библиотека JavaScript обрабатывает ответ от сервера авторизации Google. Если вы настроили прослушиватель для отслеживания изменений в состоянии входа текущего пользователя, эта функция вызывается, когда пользователь предоставляет запрошенный доступ к приложению.

Конечные точки OAuth 2.0

Сервер OAuth 2.0 отправляет ответ на redirect_uri , указанный в вашем запросе токена доступа.

Если пользователь одобряет запрос, ответ содержит токен доступа. Если пользователь не одобряет запрос, ответ содержит сообщение об ошибке. Маркер доступа или сообщение об ошибке возвращается в хэш-фрагменте URI перенаправления, как показано ниже:

  • Ответ токена доступа:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    В дополнение к параметру access_token строка фрагмента также содержит параметр token_type , который всегда имеет значение Bearer , и параметр expires_in , указывающий время жизни токена в секундах. Если параметр state был указан в запросе токена доступа, его значение также включается в ответ.

  • Ответ об ошибке:
    https://oauth2.example.com/callback#error=access_denied

Пример ответа сервера OAuth 2.0

Вы можете протестировать этот процесс, щелкнув следующий пример URL-адреса, который запрашивает доступ только для чтения для просмотра метаданных файлов на вашем Google Диске:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

После завершения потока OAuth 2.0 вы будете перенаправлены на http://localhost/oauth2callback . Этот URL-адрес приведет к ошибке 404 NOT FOUND , если только ваш локальный компьютер не обработает файл по этому адресу. Следующий шаг предоставляет более подробную информацию об информации, возвращаемой в URI, когда пользователь перенаправляется обратно в ваше приложение.

Вызов API Google

JS-клиентская библиотека

После того как ваше приложение получит токен доступа, вы можете использовать клиентскую библиотеку JavaScript для выполнения запросов API от имени пользователя. Клиентская библиотека управляет токеном доступа за вас, и вам не нужно делать ничего особенного, чтобы отправить его в запросе.

Клиентская библиотека поддерживает два способа вызова методов API. Если вы загрузили документ обнаружения, API определит для вас функции, специфичные для метода. Вы также можете использовать функцию gapi.client.request для вызова метода API. Следующие два фрагмента кода демонстрируют эти параметры для метода about.get API Drive.

// Example 1: Use method-specific function
var request = gapi.client.drive.about.get({'fields': 'user'});

// Execute the API request.
request.execute(function(response) {
  console.log(response);
});


// Example 2: Use gapi.client.request(args) function
var request = gapi.client.request({
  'method': 'GET',
  'path': '/drive/v3/about',
  'params': {'fields': 'user'}
});
// Execute the API request.
request.execute(function(response) {
  console.log(response);
});

Конечные точки OAuth 2.0

После того как ваше приложение получит токен доступа, вы можете использовать его для вызовов API Google от имени данной учетной записи пользователя, если были предоставлены области доступа, требуемые API. Для этого включите токен доступа в запрос к API, указав либо параметр запроса access_token , либо значение Bearer -заголовка Authorization HTTP. Когда это возможно, заголовок HTTP предпочтительнее, поскольку строки запроса, как правило, видны в журналах сервера. В большинстве случаев для настройки вызовов API Google можно использовать клиентскую библиотеку (например, при вызове API Drive Files ).

Вы можете опробовать все API Google и просмотреть их области действия на игровой площадке OAuth 2.0 .

Примеры HTTP-запроса

Вызов конечной точки drive.files (API Drive Files) с использованием HTTP-заголовка Authorization: Bearer может выглядеть следующим образом. Обратите внимание, что вам нужно указать свой собственный токен доступа:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Вот вызов того же API для аутентифицированного пользователя с использованием параметра строки запроса access_token :

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

примеры curl

Вы можете протестировать эти команды с помощью приложения командной строки curl . Вот пример, в котором используется параметр заголовка HTTP (предпочтительно):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Или, альтернативно, опция параметра строки запроса:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Пример кода JavaScript

Фрагмент кода ниже демонстрирует, как использовать CORS (совместное использование ресурсов из разных источников) для отправки запроса в API Google. В этом примере не используется клиентская библиотека API Google для JavaScript. Однако даже если вы не используете клиентскую библиотеку, руководство по поддержке CORS в документации этой библиотеки, скорее всего, поможет вам лучше понять эти запросы.

В этом фрагменте кода переменная access_token представляет токен, который вы получили для выполнения запросов API от имени авторизованного пользователя. Полный пример демонстрирует, как сохранить этот токен в локальном хранилище браузера и получить его при выполнении запроса API.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

Полный пример

JS-клиентская библиотека

Пример демо кода

Этот раздел содержит рабочую демонстрацию примера кода, который следует, чтобы продемонстрировать, как код ведет себя в реальном приложении. После того как вы авторизуете приложение, оно появится в списке приложений, подключенных к вашему аккаунту Google . Приложение называется OAuth 2.0 Demo for Google API Docs . Точно так же, если вы отмените доступ и обновите эту страницу, это приложение больше не будет отображаться в списке.

Обратите внимание, что это приложение запрашивает доступ к области https://www.googleapis.com/auth/drive.metadata.readonly для чтения. Доступ запрашивается только для демонстрации того, как инициировать поток OAuth 2.0 в приложении JavaScript. Это приложение не делает никаких запросов API.

Пример кода JavaScript

Как показано выше, этот пример кода предназначен для страницы (приложения), которая загружает клиентскую библиотеку API Google для JavaScript и инициирует поток OAuth 2.0. На странице отображается либо:

  • Одна кнопка, которая позволяет пользователю войти в приложение. Если пользователь ранее не авторизовал приложение, приложение запускает поток OAuth 2.0.
  • Две кнопки, которые позволяют пользователю либо выйти из приложения, либо отозвать доступ, ранее предоставленный приложению. Если вы выходите из приложения, вы не отменяете доступ, предоставленный приложению. Вам нужно будет снова войти в систему, прежде чем приложение сможет делать другие авторизованные запросы от вашего имени, но вам не нужно будет снова предоставлять доступ при следующем использовании приложения. Однако, если вы отзовете доступ, вам нужно снова предоставить доступ.

Вы также можете отозвать доступ к приложению на странице разрешений для своей учетной записи Google. Приложение указано как OAuth 2.0 Demo для Google API Docs .

<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

Конечные точки OAuth 2.0

В этом примере кода показано, как выполнить поток OAuth 2.0 в JavaScript без использования клиентской библиотеки API Google для JavaScript. Код предназначен для HTML-страницы, на которой отображается кнопка для выполнения запроса API. Если вы нажмете кнопку, код проверит, сохранила ли страница токен доступа к API в локальном хранилище вашего браузера. Если это так, он выполняет запрос API. В противном случае он инициирует поток OAuth 2.0.

Для потока OAuth 2.0 страница выполняет следующие действия:

  1. Он направляет пользователя на сервер Google OAuth 2.0, который запрашивает доступ к области https://www.googleapis.com/auth/drive.metadata.readonly .
  2. После предоставления (или отказа) доступа к одной или нескольким запрошенным областям пользователь перенаправляется на исходную страницу, которая анализирует токен доступа из строки идентификатора фрагмента.
  3. Страница использует токен доступа, чтобы сделать образец запроса API.

    Запрос API вызывает метод about.get API Диска для получения информации об учетной записи Google Диска авторизованного пользователя.

  4. Если запрос выполняется успешно, ответ API регистрируется в консоли отладки браузера.

Вы можете отозвать доступ к приложению на странице разрешений для своей учетной записи Google. Приложение будет указано как OAuth 2.0 Demo для Google API Docs .

Чтобы запустить этот код локально, вам необходимо установить значения для переменных YOUR_CLIENT_ID и YOUR_REDIRECT_URI , которые соответствуют вашим учетным данным для авторизации . Для переменной YOUR_REDIRECT_URI должен быть задан тот же URL-адрес, по которому обслуживается страница. Значение должно точно совпадать с одним из авторизованных URI перенаправления для клиента OAuth 2.0, который вы настроили в API Console Credentials page. Если это значение не соответствует авторизованному URI, вы получите ошибку redirect_uri_mismatch . В вашем проекте также должен быть включен соответствующий API для этого запроса.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Правила проверки происхождения JavaScript

Google применяет следующие правила проверки к источникам JavaScript, чтобы помочь разработчикам обеспечить безопасность своих приложений. Ваши источники JavaScript должны соответствовать этим правилам. См. раздел 3 RFC 3986 для определения домена, хоста и схемы, упомянутых ниже.

Правила проверки
Схема

Источники JavaScript должны использовать схему HTTPS, а не обычный HTTP. Это правило не распространяется на URI локального хоста (включая URI IP-адреса локального хоста).

Хозяин

Хосты не могут быть необработанными IP-адресами. IP-адреса Localhost исключены из этого правила.

Домен
  • Хост-ДВУ ( домены верхнего уровня ) должны входить в список общедоступных суффиксов .
  • Хост-домены не могут быть “googleusercontent.com” .
  • Источники JavaScript не могут содержать домены сокращения URL-адресов (например, goo.gl ), если приложение не владеет доменом.
  • Информация о пользователе

    Источники JavaScript не могут содержать подкомпонент userinfo.

    Дорожка

    Источники JavaScript не могут содержать компонент пути.

    Запрос

    Источники JavaScript не могут содержать компонент запроса.

    Фрагмент

    Источники JavaScript не могут содержать компонент фрагмента.

    Персонажи Источники JavaScript не могут содержать определенные символы, включая:
    • Подстановочные знаки ( '*' )
    • Непечатаемые символы ASCII
    • Недопустимые кодировки процентов (любая кодировка процентов, которая не соответствует форме URL-кодирования знака процента, за которым следуют две шестнадцатеричные цифры)
    • Нулевые символы (закодированный нулевой символ, например, %00 , %C0%80 )

    Инкрементная авторизация

    В протоколе OAuth 2.0 ваше приложение запрашивает авторизацию для доступа к ресурсам, которые определяются областями действия. Считается лучшей практикой для пользователей запрашивать авторизацию для ресурсов в то время, когда они вам нужны. Чтобы реализовать эту практику, сервер авторизации Google поддерживает добавочную авторизацию. Эта функция позволяет вам запрашивать области по мере необходимости и, если пользователь предоставляет разрешение на новую область, возвращает код авторизации, который можно обменять на токен, содержащий все области, которые пользователь предоставил проекту.

    Например, приложению, которое позволяет людям пробовать музыкальные треки и создавать миксы, может потребоваться очень мало ресурсов во время входа в систему, возможно, не более, чем имя человека, вошедшего в систему. Однако для сохранения готового микса потребуется доступ к их Google Диску. . Большинство людей сочли бы естественным, если бы доступ к их Google Диску запрашивался только тогда, когда приложение действительно нуждалось в этом.

    В этом случае во время входа приложение может запросить области openid и profile для выполнения базового входа, а затем запросить область https://www.googleapis.com/auth/drive.file во время первый запрос на сохранение микса.

    К токену доступа, полученному в результате инкрементной авторизации, применяются следующие правила:

    • Токен можно использовать для доступа к ресурсам, соответствующим любой из областей действия новой комбинированной авторизации.
    • Когда вы используете маркер обновления для комбинированной авторизации для получения маркера доступа, маркер доступа представляет собой комбинированную авторизацию и может использоваться для любого из значений scope , включенных в ответ.
    • Объединенная авторизация включает все области, которые пользователь предоставил проекту API, даже если разрешения были запрошены у разных клиентов. Например, если пользователь предоставил доступ к одной области с помощью настольного клиента приложения, а затем предоставил другую область тому же приложению через мобильный клиент, комбинированная авторизация будет включать обе области.
    • Если вы отзовете токен, представляющий комбинированную авторизацию, доступ ко всем областям этой авторизации от имени связанного пользователя будет отозван одновременно.

    В приведенных ниже примерах кода показано, как добавить области к существующему маркеру доступа. Такой подход позволяет вашему приложению избежать необходимости управлять несколькими маркерами доступа.

    JS-клиентская библиотека

    Чтобы добавить области к существующему токену доступа, вызовите метод GoogleUser.grant(options) . Объект options определяет дополнительные области, к которым вы хотите предоставить доступ.

    // Space-separated list of additional scope(s) you are requesting access to.
    // This code adds read-only access to the user's calendars via the Calendar API.
    var NEW_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
    
    // Retrieve the GoogleUser object for the current user.
    var GoogleUser = GoogleAuth.currentUser.get();
    GoogleUser.grant({'scope': NEW_SCOPES});

    Конечные точки OAuth 2.0

    Чтобы добавить области к существующему токену доступа, включите параметр include_granted_scopes в запрос к серверу Google OAuth 2.0 .

    Следующий фрагмент кода демонстрирует, как это сделать. Фрагмент предполагает, что вы сохранили области, для которых ваш токен доступа действителен, в локальном хранилище браузера. (The complete example code stores a list of scopes for which the access token is valid by setting the oauth2-test-params.scope property in the browser's local storage.)

    The snippet compares the scopes for which the access token is valid to the scope you want to use for a particular query. If the access token does not cover that scope, the OAuth 2.0 flow starts. Here, the oauth2SignIn function is the same as the one that was provided in step 2 (and that is provided later in the complete example ).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    Revoking a token

    In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting Account Settings . See the Remove site or app access section of the Third-party sites & apps with access to your account support document for more information.

    It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes, removes an application, or the API resources required by an app have significantly changed. In other words, part of the removal process can include an API request to ensure the permissions previously granted to the application are removed.

    JS Client Library

    To programmatically revoke a token, call GoogleAuth.disconnect() :

    GoogleAuth.disconnect();

    OAuth 2.0 Endpoints

    To programmatically revoke a token, your application makes a request to https://oauth2.googleapis.com/revoke and includes the token as a parameter:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.

    If the revocation is successfully processed, then the HTTP status code of the response is 200 . For error conditions, an HTTP status code 400 is returned along with an error code.

    The following JavaScript snippet shows how to revoke a token in JavaScript without using the Google APIs Client Library for JavaScript. Since the Google's OAuth 2.0 endpoint for revoking tokens does not support Cross-origin Resource Sharing (CORS), the code creates a form and submits the form to the endpoint rather than using the XMLHttpRequest() method to post the request.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }