Библиотека JavaScript google.accounts.oauth2
помогает запрашивать согласие пользователя и получать токен доступа для работы с пользовательскими данными. Он основан на потоке неявных грантов OAuth 2.0 и предназначен для того, чтобы вы могли либо напрямую вызывать API Google с помощью REST и CORS, либо использовать нашу клиентскую библиотеку API Google для JavaScript (также известную gapi.client
) для простого и гибкого доступа к наши более сложные API.
Прежде чем получить доступ к защищенным пользовательским данным из браузера, пользователи вашего сайта запускают процессы выбора учетной записи Google, входа в систему и получения согласия, и, наконец, серверы OAuth Google выдают и возвращают токен доступа в ваше веб-приложение.
В модели авторизации на основе токенов нет необходимости хранить токены обновления для каждого пользователя на внутреннем сервере.
Рекомендуется следовать описанному здесь подходу, а не методам, описанным в старом руководстве OAuth 2.0 для клиентских веб-приложений .
Настраивать
Найдите или создайте идентификатор клиента, выполнив действия, описанные в руководстве по получению идентификатора клиента API Google . Затем добавьте клиентскую библиотеку на страницы вашего сайта, которые будут вызывать API Google. Наконец, инициализируйте клиент токена. Обычно это делается в обработчике onload
клиентской библиотеки.
Инициализация клиента токена
Вызовите initTokenClient()
, чтобы инициализировать новый клиент токена с идентификатором клиента вашего веб-приложения. При желании вы можете включить список из одной или нескольких областей, к которым пользователю необходим доступ:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (response) => {
...
},
});
Запуск потока токенов OAuth 2.0
Используйте метод requestAccessToken()
, чтобы запустить поток пользовательского интерфейса токена и получить токен доступа. Google предлагает пользователю:
- Выберите свою учетную запись,
- войдите в учетную запись Google, если вы еще не вошли в нее,
- предоставить вашему веб-приложению согласие на доступ к каждой запрошенной области.
Жест пользователя запускает поток токенов: <button onclick="client.requestAccessToken();">Authorize me</button>
Затем Google возвращает TokenResponse
, содержащий токен доступа и список областей, к которым пользователь предоставил доступ, или ошибку, вашему обработчику обратного вызова.
Пользователи могут закрыть окно выбора учетной записи или входа в систему, и в этом случае ваша функция обратного вызова не будет вызвана.
Как обрабатывать согласие
Дизайн и пользовательский интерфейс вашего приложения должны быть реализованы только после тщательного анализа политик Google OAuth 2.0 . Эти политики охватывают работу с несколькими областями, когда и как обрабатывать согласие пользователя и многое другое.
Добавочная авторизация — это политика и методология разработки приложений, которые используются для запроса доступа к ресурсам с использованием областей только по мере необходимости, а не заранее и сразу. Пользователи могут одобрить или отклонить совместное использование отдельных ресурсов, запрошенных вашим приложением. Это называется детальными разрешениями .
Во время этого процесса Google запрашивает согласие пользователя, индивидуально перечисляя каждую запрошенную область, пользователи выбирают ресурсы, которые будут доступны вашему приложению, и, наконец, Google вызывает вашу функцию обратного вызова, чтобы вернуть токен доступа и утвержденные пользователем области. Затем ваше приложение безопасно обрабатывает различные возможные результаты с детальными разрешениями.
Инкрементная авторизация
Для веб-приложений следующие два высокоуровневых сценария демонстрируют добавочную авторизацию с использованием:
- Одностраничное приложение Ajax, часто использующее
XMLHttpRequest
с динамическим доступом к ресурсам. - Несколько веб-страниц, ресурсы разделены и управляются отдельно для каждой страницы.
Эти два сценария представлены для иллюстрации особенностей проектирования и методологий, но не претендуют на роль исчерпывающих рекомендаций о том, как встроить согласие в ваше приложение. Реальные приложения могут использовать вариацию или комбинацию этих методов.
Аякс
Добавьте поддержку добавочной авторизации в свое приложение, выполнив несколько вызовов requestAccessToken()
и используя параметр scope
объекта OverridableTokenClientConfig
для запроса отдельных областей в тот момент, когда они необходимы, и только при необходимости. В этом примере ресурсы будут запрошены и видны только после того, как жест пользователя развернет свернутый раздел содержимого.
Приложение Аякс |
---|
Инициализируйте клиент токена при загрузке страницы:const client = google.accounts.oauth2.initTokenClient({ client_id: 'YOUR_GOOGLE_CLIENT_ID', callback: "onTokenResponse", }); Документы для чтенияПоказать последние документы client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/documents.readonly' }) ); Предстоящие событияПоказать информацию календаря client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/calendar.readonly' }) ); Карусель фотографийПоказать фотографии client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/photoslibrary.readonly' }) ); |
Каждый вызов requestAccessToken
запускает момент согласия пользователя. Ваше приложение будет иметь доступ только к тем ресурсам, которые требуются для раздела, который пользователь выбирает для расширения, тем самым ограничивая совместное использование ресурсов по выбору пользователя.
Несколько веб-страниц
При разработке добавочной авторизации несколько страниц используются для запроса только тех областей, которые необходимы для загрузки страницы, что снижает сложность и необходимость выполнения нескольких вызовов для получения согласия пользователя и получения токена доступа.
Многостраничное приложение | ||||||||
---|---|---|---|---|---|---|---|---|
|
Каждая страница запрашивает необходимую область и получает токен доступа, вызывая initTokenClient()
и requestAccessToken()
во время загрузки. В этом сценарии отдельные веб-страницы используются для четкого разделения пользовательских функций и ресурсов по областям. В реальной ситуации отдельные страницы могут запрашивать несколько связанных областей.
Детализированные разрешения
Детализированные разрешения обрабатываются одинаково во всех сценариях; после того, как requestAccessToken()
вызовет вашу функцию обратного вызова и вернет токен доступа, убедитесь, что пользователь утвердил запрошенные области с помощью hasGrantedAllScopes()
или hasGrantedAnyScope()
. Например:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly \
https://www.googleapis.com/auth/documents.readonly \
https://www.googleapis.com/auth/photoslibrary.readonly',
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
'https://www.googleapis.com/auth/photoslibrary.readonly')) {
// Look at pictures
...
}
if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
'https://www.googleapis.com/auth/calendar.readonly',
'https://www.googleapis.com/auth/documents.readonly')) {
// Meeting planning and review documents
...
}
}
},
});
Любые ранее принятые гранты от предыдущих сессий или запросов также будут включены в ответ. Запись о согласии пользователя ведется для каждого пользователя и идентификатора клиента и сохраняется при нескольких вызовах initTokenClient()
или requestAccessToken()
. По умолчанию согласие пользователя необходимо только при первом посещении пользователем вашего веб-сайта и запросе новой области, но его можно запрашивать при каждой загрузке страницы с использованием prompt=consent
в объектах конфигурации Token Client.
Работа с токенами
В модели Token токен доступа не сохраняется в ОС или браузере, вместо этого новый токен сначала получается во время загрузки страницы или впоследствии путем запуска вызова requestAccessToken()
посредством жеста пользователя, такого как нажатие кнопки.
Использование REST и CORS с API Google
Токен доступа можно использовать для выполнения аутентифицированных запросов к API Google с использованием REST и CORS. Это позволяет пользователям входить в систему, давать согласие, Google выдавать токен доступа, а вашему сайту — работать с данными пользователя.
В этом примере просмотрите предстоящие события календаря вошедших в систему пользователей, используя токен доступа, возвращаемый tokenRequest()
:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();
Дополнительные сведения см. в разделе «Как использовать CORS для доступа к API Google» .
В следующем разделе рассказывается, как легко интегрироваться с более сложными API.
Работа с библиотекой JavaScript API Google.
Клиент токена работает с клиентской библиотекой Google API для JavaScript. См. фрагмент кода ниже.
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
gapi.client.setApiKey('YOUR_API_KEY');
gapi.client.load('calendar', 'v3', listUpcomingEvents);
}
},
});
function listUpcomingEvents() {
gapi.client.calendar.events.list(...);
}
Срок действия токена
По своей конструкции токены доступа имеют короткий срок действия. Если срок действия токена доступа истекает до окончания сеанса пользователя, получите новый токен, вызвав requestAccessToken()
из события, управляемого пользователем, например нажатия кнопки.
Использование токена доступа для отзыва согласия
Вызовите метод google.accounts.oauth2.revoke
, чтобы удалить согласие пользователя и доступ к ресурсам для всех областей, предоставленных вашему приложению. Для отзыва этого разрешения требуется действительный токен доступа:
google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
console.log(done);
console.log(done.successful);
console.log(done.error);
console.log(done.error_description);
});