Внедрить сервер OAuth 2.0

Каждая интеграция Cloud-to-cloud должна включать механизм аутентификации пользователей.

Аутентификация позволяет связать учётные записи Google ваших пользователей с учётными записями пользователей в вашей системе аутентификации. Это позволяет идентифицировать пользователей при получении запроса на умный дом. Умный дом Google поддерживает только OAuth с кодом авторизации.

На этой странице описывается, как настроить сервер OAuth 2.0 для работы с интеграцией Cloud-to-cloud .

Привязка аккаунта Google к OAuth

В потоке кода авторизации вам понадобятся две конечные точки:

  • Конечная точка авторизации , которая предоставляет пользовательский интерфейс входа пользователям, которые еще не вошли в систему. Конечная точка авторизации также создает кратковременный код авторизации для регистрации согласия пользователей на запрошенный доступ.

  • Конечная точка обмена токенами , которая отвечает за два типа обменов:

    1. Обменивает код авторизации на долгосрочный токен обновления и краткосрочный токен доступа. Этот обмен происходит, когда пользователь проходит процедуру привязки учётной записи.
    2. Обменивает долгосрочный токен обновления на краткосрочный токен доступа. Этот обмен происходит, когда Google требуется новый токен доступа, поскольку срок действия предыдущего истёк.

Руководство по проектированию

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

На этом рисунке показаны шаги, которые пользователь должен выполнить для привязки своей учётной записи Google к вашей системе аутентификации. На первом снимке экрана показана инициированная пользователем привязка с вашей платформы. На втором изображении показан вход пользователя в Google, а на третьем — согласие и подтверждение привязки своей учётной записи Google к вашему приложению. На последнем снимке экрана показана успешно привязанная учётная запись пользователя в приложении Google.
Рисунок 1. Вход пользователя в систему Google и экраны согласия.

Требования

  1. Вы должны сообщить, что учетная запись пользователя будет связана с Google, а не с конкретным продуктом Google, например Google Home или Google Assistant.
  2. У вас должно быть заявление об авторизации Google, например: «Выполняя вход, вы разрешаете Google управлять вашими устройствами». См. раздел «Авторизация управления устройствами Google » в Правилах разработчика Google Home.
  3. Необходимо открыть страницу привязки Web OAuth и убедиться, что у пользователей есть понятный способ входа в учётную запись Google, например, поля для ввода имени пользователя и пароля. Не используйте метод входа Google (GSI), который позволяет пользователям подключаться без перехода на страницу привязки Web OAuth. Это является нарушением политики Google.
  4. На странице привязки OAuth необходимо включить по крайней мере один из следующих элементов, чтобы указать интеграцию, к которой подключается пользователь:
    • Логотип компании
    • Название компании
    • Имя интеграции
    • Значок приложения

Рекомендации

Мы рекомендуем вам сделать следующее:

  1. Отобразите Политику конфиденциальности Google. Добавьте ссылку на Политику конфиденциальности Google на экран согласия.

  2. Данные для обмена. Чётко и ясно объясните пользователю, какие данные Google требует от него и почему.

  3. Чёткий призыв к действию. Разместите чёткий призыв к действию на экране согласия, например, «Согласиться и подключиться». Это необходимо, поскольку пользователям необходимо понимать, какие данные им необходимо предоставить Google для подключения своих аккаунтов.

  4. Возможность отмены. Предоставьте пользователям возможность вернуться назад или отменить подписку, если они решили не использовать ссылку.

  5. Прозрачный процесс входа. Убедитесь, что у пользователей есть понятный способ входа в учётную запись Google, например, поля для имени пользователя и пароля или «Войти через Google» .

  6. Возможность отмены привязки. Предложите пользователям механизм отмены привязки, например, URL-адрес для доступа к настройкам их учётной записи на вашей платформе. Кроме того, вы можете добавить ссылку на учётную запись Google , где пользователи смогут управлять своей привязанной учётной записью.

  7. Возможность смены учётной записи пользователя. Предложите пользователям способ переключения учётных записей. Это особенно полезно, если пользователи часто используют несколько учётных записей.

    • Если пользователю необходимо закрыть экран согласия для переключения учетных записей, отправьте в Google устранимую ошибку, чтобы пользователь мог войти в нужную учетную запись с привязкой OAuth .
  8. Добавьте свой логотип. Разместите логотип вашей компании на экране согласия. Разместите логотип в соответствии с вашими рекомендациями по стилю. Если вы также хотите разместить логотип Google, см. раздел «Логотипы и товарные знаки» .

Поток кода авторизации

Реализация потока кодов авторизации на сервере OAuth 2.0 состоит из двух конечных точек, к которым ваш сервис предоставляет доступ по протоколу HTTPS. Первая конечная точка — это конечная точка авторизации, которая отвечает за поиск и получение согласия пользователей на доступ к данным. Конечная точка авторизации предоставляет пользовательский интерфейс входа для пользователей, которые ещё не вошли в систему, и регистрирует согласие на запрошенный доступ. Вторая конечная точка — это конечная точка обмена токенами, которая используется для получения зашифрованных строк, называемых токенами, которые авторизуют пользователя для доступа к вашему сервису.

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

Сеанс потока кода авторизации OAuth 2.0, инициированный Google, имеет следующий поток:

  1. Google открывает вашу конечную точку авторизации в браузере пользователя. Если поток действий был запущен на устройстве, поддерживающем только голосовой ввод, Google переносит выполнение на телефон.
  2. Пользователь входит в систему, если он еще не вошел в систему, и предоставляет Google разрешение на доступ к своим данным через ваш API, если он еще не предоставил такое разрешение.
  3. Ваш сервис создаёт код авторизации и возвращает его Google. Для этого перенаправьте браузер пользователя обратно в Google, прикрепив код авторизации к запросу.
  4. Google отправляет код авторизации на вашу конечную точку обмена токенами, которая проверяет его подлинность и возвращает токен доступа и токен обновления . Токен доступа — это краткосрочный токен, который ваш сервис принимает в качестве учётных данных для доступа к API. Токен обновления — это долгосрочный токен, который Google может хранить и использовать для получения новых токенов доступа по истечении их срока действия.
  5. После того как пользователь завершит процесс привязки аккаунта, каждый последующий запрос, отправленный из Google, будет содержать токен доступа.

Обработка запросов на авторизацию

Когда вам необходимо выполнить привязку аккаунта с использованием потока кодов авторизации OAuth 2.0, Google отправляет пользователя на вашу конечную точку авторизации с запросом, который включает следующие параметры:

Параметры конечной точки авторизации
client_id Идентификатор клиента, который вы присвоили Google.
redirect_uri URL, на который вы отправляете ответ на этот запрос.
state Учетное значение, которое передается обратно в Google без изменений в URI перенаправления.
scope Необязательно: разделенный пробелами набор строк области действия, которые определяют данные, для которых Google запрашивает авторизацию.
response_type Тип значения, возвращаемого в ответе. Для потока авторизации OAuth 2.0 тип ответа всегда — code .

Например, если ваша конечная точка авторизации доступна по адресу https://myservice.example.com/auth , запрос может выглядеть следующим образом:

GET https://myservice.example.com/auth?client_id=GOOGLE_CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE_STRING&scope=REQUESTED_SCOPES&response_type=code

Чтобы ваша конечная точка авторизации могла обрабатывать запросы на вход, выполните следующие действия:

  1. Убедитесь, что client_id соответствует Client ID, назначенному вами Google, а redirect_uri — URL-адресу перенаправления, предоставленному Google для вашего сервиса. Эти проверки важны для предотвращения предоставления доступа непреднамеренным или неправильно настроенным клиентским приложениям. Если вы поддерживаете несколько потоков OAuth 2.0, также убедитесь, что response_typecode .
  2. Проверьте, вошёл ли пользователь в ваш сервис. Если нет, выполните процедуру входа или регистрации в вашем сервисе.
  3. Сгенерируйте код авторизации, который Google будет использовать для доступа к вашему API. Код авторизации может быть любым строковым значением, но он должен однозначно отражать имя пользователя, клиента, которому предназначен токен, и срок действия кода. Код не должен быть угадываемым. Обычно выдаются коды авторизации, срок действия которых составляет примерно 10 минут.
  4. Убедитесь, что URL-адрес, указанный параметром redirect_uri , имеет следующий вид:
       https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID   https://oauth-redirect-sandbox.googleusercontent.com/r/YOUR_PROJECT_ID   
  5. Перенаправьте браузер пользователя на URL-адрес, указанный параметром redirect_uri . Добавьте только что сгенерированный код авторизации и исходное, неизменённое значение состояния при перенаправлении, добавив параметры code и state . Ниже приведён пример полученного URL-адреса:
    https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID?code=AUTHORIZATION_CODE&state=STATE_STRING

Обработка запросов на обмен токенами

Конечная точка обмена токенами вашего сервиса отвечает за два вида обмена токенами:

  • Обмен кодами авторизации на токены доступа и токены обновления
  • Обмен токенов обновления на токены доступа

Запросы на обмен токенами включают следующие параметры:

Параметры конечной точки обмена токенами
client_id Строка, идентифицирующая источник запроса как Google. Эта строка должна быть зарегистрирована в вашей системе как уникальный идентификатор Google.
client_secret Секретная строка, которую вы зарегистрировали в Google для своего сервиса.
grant_type Тип обмениваемого токена. Это может быть authorization_code или refresh_token .
code Если grant_type=authorization_code , этот параметр представляет собой код, полученный Google либо от вашей конечной точки входа, либо от конечной точки обмена токенами.
redirect_uri Если grant_type=authorization_code , этот параметр представляет собой URL-адрес, используемый в первоначальном запросе авторизации.
refresh_token Если grant_type=refresh_token , этот параметр представляет собой токен обновления, который Google получил от вашей конечной точки обмена токенами.

Настройте, как Google отправляет учетные данные на ваш сервер

В зависимости от реализации ваш сервер авторизации ожидает получить учетные данные клиента либо в теле запроса, либо в заголовке запроса.

По умолчанию Google отправляет учётные данные в теле запроса. Если ваш сервер авторизации требует, чтобы учётные данные клиента были в заголовке запроса, необходимо соответствующим образом настроить интеграцию Cloud-to-cloud :

Перейти в консоль разработчика

  1. В списке проектов нажмите кнопку Открыть рядом с проектом, с которым вы хотите работать.

  2. В разделе «Облако-облако» выберите «Разработка» .

  3. Нажмите Открыть рядом с вашей интеграцией.

  4. Прокрутите страницу вниз до раздела Разрешения (необязательно) и установите флажок Разрешить Google передавать идентификатор клиента и секрет через базовый заголовок аутентификации HTTP .

  5. Нажмите «Сохранить» , чтобы сохранить изменения.

Обмен кодами авторизации на токены доступа и токены обновления

После того как пользователь войдет в систему и ваша конечная точка авторизации вернет Google кратковременный код авторизации, Google отправит запрос вашей конечной точке обмена токенами, чтобы обменять код авторизации на токен доступа и токен обновления.

Для этих запросов значение параметра grant_type равно authorization_code , а значение параметра code — значению кода авторизации, который вы ранее предоставили Google. Ниже приведён пример запроса на обмен кода авторизации на токен доступа и токен обновления:

 POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded  client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=REDIRECT_URI 

Для обмена кодами авторизации для токена доступа и токена обновления ваша конечная точка обмена токенами отвечает на запросы POST , выполняя следующие шаги:

  1. Убедитесь, что client_id идентифицирует источник запроса как авторизованный источник, а client_secret соответствует ожидаемому значению.
  2. Убедитесь, что код авторизации действителен и не просрочен, а также что идентификатор клиента, указанный в запросе, совпадает с идентификатором клиента, связанным с кодом авторизации.
  3. Убедитесь, что URL-адрес, указанный параметром redirect_uri , идентичен значению, использованному в первоначальном запросе авторизации.
  4. Если вы не можете проверить все вышеперечисленные критерии, верните ошибку HTTP 400 Bad Request с {"error": "invalid_grant"} в качестве тела.
  5. В противном случае используйте идентификатор пользователя из кода авторизации для генерации токена обновления и токена доступа. Эти токены могут иметь любое строковое значение, но они должны однозначно соответствовать пользователю и клиенту, для которых предназначен токен, и не должны быть угадываемыми. Для токенов доступа также запишите срок действия токена, который обычно составляет один час после выдачи токена. Токены обновления не имеют срока действия.
  6. Верните следующий объект JSON в теле HTTPS-ответа:
    { "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "refresh_token": "REFRESH_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }

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

Обмен токенов обновления на токены доступа

Когда срок действия токена доступа истекает, Google отправляет запрос на вашу конечную точку обмена токенами для обмена токена обновления на новый токен доступа.

Для этих запросов значение параметра grant_typerefresh_token , а значение параметра refresh_token — значение токена обновления, который вы ранее предоставили Google. Ниже приведён пример запроса на обмен токена обновления на токен доступа:

 POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded  client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET&grant_type=refresh_token&refresh_token=REFRESH_TOKEN 

Чтобы обменять токен обновления на токен доступа, ваша конечная точка обмена токенами отвечает на запросы POST , выполняя следующие шаги:

  1. Убедитесь, что client_id идентифицирует источник запроса как Google, а client_secret соответствует ожидаемому значению.
  2. Убедитесь, что токен обновления действителен и что идентификатор клиента, указанный в запросе, совпадает с идентификатором клиента, связанным с токеном обновления.
  3. Если вы не можете проверить все вышеперечисленные критерии, верните ошибку HTTP 400 Bad Request с {"error": "invalid_grant"} в качестве тела.
  4. В противном случае используйте идентификатор пользователя из токена обновления для генерации токена доступа. Эти токены могут иметь любое строковое значение, но они должны однозначно представлять пользователя и клиента, для которого предназначен токен, и не должны быть угадываемыми. Для токенов доступа также запишите срок действия токена, обычно через час после его выдачи.
  5. Верните следующий объект JSON в теле HTTPS-ответа:
     { "token_type": "Bearer", "access_token": " ACCESS_TOKEN ", "expires_in": SECONDS_TO_EXPIRATION }

Обработка запросов информации о пользователях

Конечная точка userinfo — это ресурс, защищенный OAuth 2.0, который возвращает утверждения о связанном пользователе. Реализация и размещение конечной точки userinfo не является обязательной, за исключением следующих случаев использования:

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

заголовки запроса конечной точки userinfo
Authorization header Токен доступа типа Bearer.

Например, если ваша конечная точка userinfo доступна по адресу https://myservice.example.com/userinfo , запрос может выглядеть следующим образом:

 GET /userinfo HTTP/1.1 Host: myservice.example.com Authorization: Bearer ACCESS_TOKEN 

Чтобы ваша конечная точка userinfo могла обрабатывать запросы, выполните следующие действия:

  1. Извлеките токен доступа из заголовка авторизации и верните информацию для пользователя, связанного с токеном доступа.
  2. Если токен доступа недействителен, верните ошибку HTTP 401 Unauthorized с использованием заголовка ответа WWW-Authenticate . Ниже приведен пример ответа об ошибке с информацией о пользователе:
     HTTP/1.1 401 Unauthorized WWW-Authenticate: error="invalid_token", error_description="The Access Token expired" 
    Если в процессе связывания возвращается ошибка 401 Unauthorized или любой другой неудачный ответ об ошибке, ошибка будет невосстановимой, полученный токен будет отброшен, и пользователю придется снова инициировать процесс связывания.
  3. Если токен доступа действителен, верните ответ HTTP 200 со следующим объектом JSON в теле ответа HTTPS:

    { "sub": "USER_UUID", "email": "EMAIL_ADDRESS", "given_name": "FIRST_NAME", "family_name": "LAST_NAME", "name": "FULL_NAME", "picture": "PROFILE_PICTURE", }
    Если ваша конечная точка userinfo возвращает успешный ответ HTTP 200, полученный токен и утверждения регистрируются в учетной записи Google пользователя.
    ответ конечной точки с информацией о пользователе
    sub Уникальный идентификатор, идентифицирующий пользователя в вашей системе.
    email Адрес электронной почты пользователя.
    given_name Необязательно: Имя пользователя.
    family_name Необязательно: фамилия пользователя.
    name Необязательно: Полное имя пользователя.
    picture Необязательно: изображение профиля пользователя.