В этом документе объясняется, как реализовать авторизацию 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 Google и службы идентификации Google
Если вы используете клиентскую библиотеку API Google для JavaScript для выполнения авторизованных вызовов в Google, вам следует использовать библиотеку JavaScript Google Identity Services для обработки потока OAuth 2.0. Пожалуйста, ознакомьтесь с моделью маркера Google Identity Services, которая основана на неявном потоке предоставления OAuth 2.0.
Предпосылки
Включите API для вашего проекта
Любое приложение, которое вызывает API Google, должно включить эти API в .
Чтобы включить API для вашего проекта:
- в .
- The перечисляет все доступные API, сгруппированные по семейству продуктов и популярности. Если API, который вы хотите включить, не отображается в списке, используйте поиск, чтобы найти его, или нажмите «Просмотреть все» в семействе продуктов, к которому он принадлежит.
- Выберите API, который вы хотите включить, затем нажмите кнопку Включить .
Создать учетные данные для авторизации
Любое приложение, использующее OAuth 2.0 для доступа к API Google, должно иметь учетные данные авторизации, которые идентифицируют приложение на сервере OAuth 2.0 Google. Следующие шаги объясняют, как создать учетные данные для вашего проекта. Затем ваши приложения могут использовать учетные данные для доступа к API, которые вы включили для этого проекта.
- Нажмите «Создать клиента» .
- Выберите тип приложения Веб-приложение .
- Заполните форму. Приложения, которые используют JavaScript для выполнения авторизованных запросов API Google, должны указывать авторизованные источники JavaScript . Источники определяют домены, с которых ваше приложение может отправлять запросы на сервер OAuth 2.0. Эти источники должны соответствовать правилам проверки Google .
Определить области доступа
Области действия позволяют вашему приложению запрашивать доступ только к тем ресурсам, которые ему нужны, а также позволяют пользователям контролировать объем доступа, который они предоставляют вашему приложению. Таким образом, может существовать обратная зависимость между количеством запрошенных областей действия и вероятностью получения согласия пользователя.
Прежде чем приступить к реализации авторизации OAuth 2.0, мы рекомендуем вам определить области, для доступа к которым вашему приложению потребуется разрешение.
Документ «Области действия API OAuth 2.0» содержит полный список областей действия, которые можно использовать для доступа к API Google.
Получение токенов доступа OAuth 2.0
Следующие шаги показывают, как ваше приложение взаимодействует с сервером OAuth 2.0 Google для получения согласия пользователя на выполнение запроса API от имени пользователя. Ваше приложение должно иметь это согласие, прежде чем оно сможет выполнить запрос API Google, требующий авторизации пользователя.
Шаг 1: Перенаправление на сервер Google OAuth 2.0
Чтобы запросить разрешение на доступ к данным пользователя, перенаправьте пользователя на сервер Google OAuth 2.0.
Конечные точки OAuth 2.0
Создайте URL-адрес для запроса доступа из конечной точки Google OAuth 2.0 по адресу https://accounts.google.com/o/oauth2/v2/auth
. Эта конечная точка доступна по протоколу HTTPS; простые HTTP-подключения отклоняются.
Сервер авторизации Google поддерживает следующие параметры строки запроса для приложений веб-сервера:
Параметры | |||||||
---|---|---|---|---|---|---|---|
client_id | Необходимый Идентификатор клиента для вашего приложения. Вы можете найти это значение в . | ||||||
redirect_uri | Необходимый Определяет, куда сервер API перенаправляет пользователя после того, как пользователь завершает поток авторизации. Значение должно точно соответствовать одному из авторизованных URI перенаправления для клиента OAuth 2.0, который вы настроили в клиенте . Если это значение не соответствует авторизованному URI перенаправления для предоставленного Обратите внимание, что схема | ||||||
response_type | Необходимый Приложения JavaScript должны установить значение параметра | ||||||
scope | Необходимый Разделенный пробелами список областей, которые определяют ресурсы, к которым ваше приложение может получить доступ от имени пользователя. Эти значения информируют экран согласия, который Google отображает пользователю. Области действия позволяют вашему приложению запрашивать доступ только к тем ресурсам, которые ему нужны, а также позволяют пользователям контролировать объем доступа, который они предоставляют вашему приложению. Таким образом, существует обратная зависимость между количеством запрошенных областей действия и вероятностью получения согласия пользователя. Мы рекомендуем, чтобы ваше приложение запрашивало доступ к областям авторизации в контексте, когда это возможно. Запрашивая доступ к данным пользователя в контексте, с помощью инкрементальной авторизации , вы помогаете пользователям легче понять, почему вашему приложению нужен запрашиваемый им доступ. | ||||||
state | Рекомендовано Указывает любое строковое значение, которое ваше приложение использует для поддержания состояния между вашим запросом авторизации и ответом сервера авторизации. Сервер возвращает точное значение, которое вы отправляете как пару Этот параметр можно использовать для нескольких целей, например, для направления пользователя на правильный ресурс в вашем приложении, отправки одноразовых кодов и предотвращения подделки межсайтовых запросов. Поскольку ваш | ||||||
include_granted_scopes | Необязательный Позволяет приложениям использовать инкрементальную авторизацию для запроса доступа к дополнительным областям в контексте. Если вы установите значение этого параметра равным | ||||||
enable_granular_consent | Необязательный По умолчанию Когда Google включит детальные разрешения для приложения, этот параметр больше не будет иметь никакого эффекта. | ||||||
login_hint | Необязательный Если ваше приложение знает, какой пользователь пытается пройти аутентификацию, оно может использовать этот параметр для предоставления подсказки серверу аутентификации Google. Сервер использует подсказку для упрощения процесса входа либо путем предварительного заполнения поля электронной почты в форме входа, либо путем выбора соответствующей сессии множественного входа. Задайте в качестве значения параметра адрес электронной почты или | ||||||
prompt | Необязательный Разделенный пробелами, чувствительный к регистру список запросов для представления пользователю. Если вы не укажете этот параметр, пользователю будет предложено только в первый раз, когда ваш проект запросит доступ. Для получения дополнительной информации см. Запрос повторного согласия . Возможные значения:
|
Пример перенаправления на сервер авторизации Google
Пример URL-адреса показан ниже с переносами строк и пробелами для удобства чтения.
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.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 не поддерживает Cross-Origin Resource Sharing (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 https://www.googleapis.com/auth/calendar.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(); }
Шаг 2: 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 для Android от OpenID Foundation .
Веб-разработчики могут столкнуться с этой ошибкой, когда приложение Android открывает общую веб-ссылку во встроенном пользовательском агенте, а пользователь переходит на конечную точку авторизации Google OAuth 2.0 с вашего сайта. Разработчики должны разрешить открытие общих ссылок в обработчике ссылок по умолчанию операционной системы, который включает как обработчики ссылок приложений Android , так и приложение браузера по умолчанию. Библиотека Android Custom Tabs также является поддерживаемой опцией.
iOS
Разработчики iOS и macOS могут столкнуться с этой ошибкой при открытии запросов авторизации вWKWebView
. Вместо этого разработчикам следует использовать библиотеки iOS, такие как Google Sign-In для iOS или AppAuth от OpenID Foundation для iOS .
Веб-разработчики могут столкнуться с этой ошибкой, когда приложение iOS или macOS открывает общую веб-ссылку во встроенном пользовательском агенте, а пользователь переходит на конечную точку авторизации Google OAuth 2.0 с вашего сайта. Разработчики должны разрешить открытие общих ссылок в обработчике ссылок по умолчанию операционной системы, который включает как обработчики Universal Links , так и приложение браузера по умолчанию. БиблиотекаSFSafariViewController
также является поддерживаемой опцией.
org_internal
Идентификатор клиента OAuth в запросе является частью проекта, ограничивающего доступ к аккаунтам Google в определенной организации Google Cloud . Для получения дополнительной информации об этом параметре конфигурации см. раздел Тип пользователя в справочной статье Настройка экрана согласия OAuth.
invalid_client
Источник, из которого был сделан запрос, не авторизован для этого клиента. См. origin_mismatch
.
deleted_client
Клиент OAuth, используемый для выполнения запроса, был удален. Удаление может происходить вручную или автоматически в случае неиспользуемых клиентов . Удаленные клиенты могут быть восстановлены в течение 30 дней с момента удаления. Узнать больше .
invalid_grant
При использовании инкрементальной авторизации токен мог устареть или стать недействительным. Повторно аутентифицируйте пользователя и запросите его согласие на получение новых токенов. Если вы продолжаете видеть эту ошибку, убедитесь, что ваше приложение настроено правильно и что вы используете правильные токены и параметры в своем запросе. В противном случае учетная запись пользователя могла быть удалена или отключена.
origin_mismatch
Схема, домен и/или порт JavaScript, инициирующего запрос авторизации, могут не совпадать с авторизованным URI источника JavaScript, зарегистрированным для идентификатора клиента OAuth. Проверьте авторизованные источники JavaScript в .
redirect_uri_mismatch
redirect_uri
переданный в запросе авторизации, не соответствует авторизованному URI перенаправления для идентификатора клиента OAuth. Проверьте авторизованные URI перенаправления в .
Схема, домен и/или порт JavaScript, инициирующего запрос авторизации, могут не совпадать с авторизованным URI источника JavaScript, зарегистрированным для идентификатора клиента OAuth. Проверьте авторизованные источники JavaScript в .
Параметр redirect_uri
может ссылаться на поток OAuth out-of-band (OOB), который устарел и больше не поддерживается. Обратитесь к руководству по миграции , чтобы обновить вашу интеграцию.
invalid_request
Что-то не так с вашим запросом. Это может быть вызвано рядом причин:
- Запрос не был правильно отформатирован.
- В запросе отсутствовали обязательные параметры
- Запрос использует метод авторизации, который Google не поддерживает. Убедитесь, что ваша интеграция OAuth использует рекомендуемый метод интеграции
Шаг 3: Обработка ответа сервера OAuth 2.0
Конечные точки 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 Диске и доступ только для чтения для просмотра событий вашего Google Календаря:
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.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, когда пользователь перенаправляется обратно в ваше приложение.
Шаг 4: Проверьте, какие области действия предоставили пользователи
При запросе нескольких разрешений (областей действия) пользователи могут не предоставить вашему приложению доступ ко всем из них. Ваше приложение должно проверять, какие области действия были фактически предоставлены, и корректно обрабатывать ситуации, когда некоторые разрешения отклоняются, обычно отключая функции, которые полагаются на эти отклоненные области действия.
Однако есть исключения. Приложения Google Workspace Enterprise с делегированием полномочий на весь домен или приложения, помеченные как Trusted , обходят экран согласия на детализированные разрешения. Для этих приложений пользователи не увидят экран согласия на детализированные разрешения. Вместо этого ваше приложение либо получит все запрошенные области, либо ни одной.
Более подробную информацию см. в разделе Как работать с детализированными разрешениями .
Конечные точки OAuth 2.0
Чтобы проверить, предоставил ли пользователь вашему приложению доступ к определенной области, проверьте поле scope
в ответе токена доступа. Области доступа, предоставленные access_token, выражены в виде списка разделенных пробелами, чувствительных к регистру строк.
Например, следующий пример ответа токена доступа указывает на то, что пользователь предоставил вашему приложению доступ только для чтения к действиям Диска и событиям Календаря:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Вызов API Google
Конечные точки OAuth 2.0
После того, как ваше приложение получит токен доступа, вы можете использовать токен для выполнения вызовов API Google от имени данной учетной записи пользователя, если область(ы) доступа, требуемые API, были предоставлены. Для этого включите токен доступа в запрос к API, включив либо параметр запроса access_token
, либо значение заголовка HTTP Authorization
Bearer
. Когда это возможно, заголовок HTTP предпочтительнее, поскольку строки запроса, как правило, видны в журналах сервера. В большинстве случаев вы можете использовать клиентскую библиотеку для настройки вызовов API Google (например, при вызове API файлов Drive ).
Вы можете опробовать все API Google и ознакомиться с их возможностями на OAuth 2.0 Playground .
Примеры HTTP GET
Вызов конечной точки 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 (Cross-origin resource sharing) для отправки запроса в 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);
Полный пример
Конечные точки OAuth 2.0
В этом примере кода показано, как выполнить поток OAuth 2.0 в JavaScript без использования клиентской библиотеки API Google для JavaScript. Код предназначен для HTML-страницы, которая отображает кнопку для попытки запроса API. Если вы нажмете кнопку, код проверит, сохранила ли страница токен доступа API в локальном хранилище вашего браузера. Если да, он выполняет запрос API. В противном случае он инициирует поток OAuth 2.0.
Для потока OAuth 2.0 страница выполняет следующие шаги:
- Он направляет пользователя на сервер OAuth 2.0 Google, который запрашивает доступ к областям
https://www.googleapis.com/auth/drive.metadata.readonly
иhttps://www.googleapis.com/auth/calendar.readonly
. - После предоставления (или запрета) доступа к одной или нескольким запрошенным областям пользователь перенаправляется на исходную страницу, которая анализирует токен доступа из строки идентификатора фрагмента.
- На странице проверяется, к каким областям доступа пользователь предоставил доступ приложению.
Если пользователь предоставил доступ к запрошенным областям, страница использует токен доступа для выполнения запроса API-интерфейса.
Запрос API вызывает метод
about.get
API Диска для получения информации об учетной записи Google Диска авторизованного пользователя.- Если запрос выполнен успешно, ответ API регистрируется в консоли отладки браузера.
Вы можете отозвать доступ к приложению через страницу разрешений для вашего аккаунта Google. Приложение будет указано как OAuth 2.0 Demo for Google API Docs .
Чтобы запустить этот код локально, вам необходимо задать значения для переменных YOUR_CLIENT_ID
и YOUR_REDIRECT_URI
, которые соответствуют вашим учетным данным авторизации . Переменная YOUR_REDIRECT_URI
должна быть установлена на тот же URL, где обслуживается страница. Значение должно точно соответствовать одному из авторизованных URI перенаправления для клиента OAuth 2.0, который вы настроили в . Если это значение не соответствует авторизованному URI, вы получите ошибку redirect_uri_mismatch
. Ваш проект также должен включить соответствующий API для этого запроса.
<html><head></head><body> <script> var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE'; var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE'; // Parse query string to see if page request is coming from OAuth 2.0 server. var fragmentString = location.hash.substring(1); var params = {}; var regex = /([^&=]+)=([^&]*)/g, m; while (m = regex.exec(fragmentString)) { params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); } if (Object.keys(params).length > 0 && params['state']) { if (params['state'] == localStorage.getItem('state')) { localStorage.setItem('oauth2-test-params', JSON.stringify(params) ); trySampleRequest(); } else { console.log('State mismatch. Possible CSRF attack'); } } // Function to generate a random state value function generateCryptoRandomState() { const randomValues = new Uint32Array(2); window.crypto.getRandomValues(randomValues); // Encode as UTF-8 const utf8Encoder = new TextEncoder(); const utf8Array = utf8Encoder.encode( String.fromCharCode.apply(null, randomValues) ); // Base64 encode the UTF-8 data return btoa(String.fromCharCode.apply(null, utf8Array)) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); } // 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']) { // User authorized the request. Now, check which scopes were granted. if (params['scope'].includes('https://www.googleapis.com/auth/drive.metadata.readonly')) { // User authorized read-only Drive activity permission. // Calling the APIs, etc. 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 { // User didn't authorize read-only Drive activity permission. // Update UX and application accordingly console.log('User did not authorize read-only Drive activity permission.'); } // Check if user authorized Calendar read permission. if (params['scope'].includes('https://www.googleapis.com/auth/calendar.readonly')) { // User authorized Calendar read permission. // Calling the APIs, etc. console.log('User authorized Calendar read permission.'); } else { // User didn't authorize Calendar read permission. // Update UX and application accordingly console.log('User did not authorize Calendar read permission.'); } } else { oauth2SignIn(); } } /* * Create form to request access token from Google's OAuth 2.0 server. */ function oauth2SignIn() { // create random state value and store in local storage var state = generateCryptoRandomState(); localStorage.setItem('state', state); // 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 https://www.googleapis.com/auth/calendar.readonly', 'state': state, '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 (включая локальные IP-адреса URI) исключены из этого правила. |
Хозяин | Хосты не могут быть сырыми IP-адресами. IP-адреса локальных хостов исключены из этого правила. |
Домен | “googleusercontent.com” .goo.gl ), если только приложение не владеет доменом. |
Информация о пользователе | Источники JavaScript не могут содержать подкомпонент userinfo. |
Путь | Источники JavaScript не могут содержать компонент пути. |
Запрос | Источники JavaScript не могут содержать компонент запроса. |
Фрагмент | Источники JavaScript не могут содержать фрагментный компонент. |
Персонажи | Источники JavaScript не могут содержать определенные символы, включая:
|
Инкрементная авторизация
В протоколе OAuth 2.0 ваше приложение запрашивает авторизацию для доступа к ресурсам, которые идентифицируются по областям действия. Считается лучшей практикой для пользователя запрашивать авторизацию для ресурсов в то время, когда они вам нужны. Чтобы реализовать эту практику, сервер авторизации Google поддерживает инкрементальную авторизацию. Эта функция позволяет вам запрашивать области действия по мере необходимости и, если пользователь предоставляет разрешение на новую область действия, возвращает код авторизации, который можно обменять на токен, содержащий все области действия, которые пользователь предоставил проекту.
Например, приложение, позволяющее людям сэмплировать музыкальные треки и создавать миксы, может потребовать совсем немного ресурсов при входе в систему, возможно, не более, чем имя человека, который входит в систему. Однако сохранение готового микса потребует доступа к их Google Drive. Большинству людей будет естественно, если их попросят предоставить доступ к их Google Drive только в тот момент, когда приложению это действительно понадобится.
В этом случае во время входа приложение может запросить области действия openid
и profile
для выполнения базового входа, а затем позже запросить область действия https://www.googleapis.com/auth/drive.file
во время первого запроса для сохранения микса.
К токену доступа, полученному в результате инкрементной авторизации, применяются следующие правила:
- Токен можно использовать для доступа к ресурсам, соответствующим любой из областей, включенных в новую комбинированную авторизацию.
- При использовании токена обновления для комбинированной авторизации с целью получения токена доступа токен доступа представляет собой комбинированную авторизацию и может использоваться для любого из значений
scope
, включенных в ответ. - Объединенная авторизация включает все области, которые пользователь предоставил проекту API, даже если гранты были запрошены у разных клиентов. Например, если пользователь предоставил доступ к одной области с помощью настольного клиента приложения, а затем предоставил другую область тому же приложению через мобильный клиент, объединенная авторизация будет включать обе области.
- Если вы отзовете токен, представляющий комбинированную авторизацию, доступ ко всем областям этой авторизации от имени соответствующего пользователя будет отозван одновременно.
Примеры кода ниже показывают, как добавить области действия к существующему токену доступа. Такой подход позволяет вашему приложению избежать необходимости управлять несколькими токенами доступа.
Конечные точки OAuth 2.0
Чтобы добавить области действия к существующему токену доступа, включите параметр include_granted_scopes
в свой запрос к серверу Google OAuth 2.0 .
Следующий фрагмент кода демонстрирует, как это сделать. Фрагмент предполагает, что вы сохранили области, для которых ваш токен доступа действителен, в локальном хранилище браузера. ( Полный пример кода сохраняет список областей, для которых токен доступа действителен, устанавливая свойство oauth2-test-params.scope
в локальном хранилище браузера.)
Фрагмент сравнивает области, для которых токен доступа действителен, с областью, которую вы хотите использовать для конкретного запроса. Если токен доступа не покрывает эту область, запускается поток OAuth 2.0. Здесь функция oauth2SignIn
та же, что была предоставлена на шаге 2 (и которая предоставлена далее в полном примере ).
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. }
Отзыв токена
В некоторых случаях пользователь может захотеть отозвать доступ, предоставленный приложению. Пользователь может отозвать доступ, посетив Настройки учетной записи . Дополнительную информацию см. в разделе Удалить доступ к сайту или приложению в документе поддержки Сторонние сайты и приложения с доступом к вашей учетной записи .
Приложение также может программно отозвать предоставленный ему доступ. Программный отзыв важен в случаях, когда пользователь отписывается, удаляет приложение или ресурсы API, необходимые приложению, существенно изменились. Другими словами, часть процесса удаления может включать запрос API, чтобы гарантировать, что разрешения, ранее предоставленные приложению, будут удалены.
Конечные точки OAuth 2.0
Чтобы программно отозвать токен, ваше приложение отправляет запрос на https://oauth2.googleapis.com/revoke
и включает токен в качестве параметра:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
Токен может быть токеном доступа или токеном обновления. Если токен является токеном доступа и у него есть соответствующий токен обновления, токен обновления также будет отозван.
Если отзыв успешно обработан, то код статуса HTTP ответа равен 200
В случае возникновения ошибок возвращается код статуса HTTP 400
вместе с кодом ошибки.
Следующий фрагмент JavaScript показывает, как отозвать токен в JavaScript без использования клиентской библиотеки API Google для JavaScript. Поскольку конечная точка OAuth 2.0 Google для отзыва токенов не поддерживает Cross-origin Resource Sharing (CORS), код создает форму и отправляет ее в конечную точку вместо использования метода XMLHttpRequest()
для отправки запроса.
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(); }
Реализация защиты перекрестных счетов
Дополнительным шагом, который вам следует предпринять для защиты учетных записей пользователей, является внедрение Cross-Account Protection с помощью службы Cross-Account Protection от Google. Эта служба позволяет вам подписываться на уведомления о событиях безопасности, которые предоставляют вашему приложению информацию о важных изменениях в учетной записи пользователя. Затем вы можете использовать эту информацию для выполнения действий в зависимости от того, как вы решите реагировать на события.
Вот некоторые примеры типов событий, отправляемых в ваше приложение службой защиты перекрестных аккаунтов Google:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
-
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
Дополнительную информацию о реализации защиты перекрестных учетных записей и полный список доступных событий см. на странице Защита учетных записей пользователей с помощью защиты перекрестных учетных записей.