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

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

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

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

Привязка учетной записи Google с помощью OAut

In the authorization code flow, you need two endpoints:

  • The authorization endpoint, which presents the sign-in UI to your users that aren't already signed in. The authorization endpoint also creates a short-lived authorization code to record users' consent to the requested access.

  • The token exchange endpoint, which is responsible for two types of exchanges:

    1. Exchanges an authorization code for a long-lived refresh token and a short-lived access token. This exchange happens when the user goes through the account linking flow.
    2. Exchanges a long-lived refresh token for a short-lived access token. This exchange happens when Google needs a new access token because the one it had expired.

Design guidelines

This section describes the design requirements and recommendations for the user screen that you host for OAuth linking flows. After it's called by Google's app, your platform displays a sign in to Google page and account linking consent screen to the user. The user is directed back to Google's app after giving their consent to link accounts.

This figure shows the steps for a user to link their Google account
            to your authentication system. The first screenshot shows
            user-initiated linking from your platform. The second image shows
            user sign-in to Google, while the third shows the user consent and
            confirmation for linking their Google account with your app. The
            final screenshot shows a successfully linked user account in the
            Google app.
Figure 1. Account linking user sign in to Google and consent screens.

Requirements

  1. You must communicate that the user’s account will be linked to Google, not a specific Google product like Google Home or Google Assistant.
  2. You must have a Google authorization statement such as "By signing in, you are authorizing Google to control your devices." See the Google Device Control Authorization section of the Google Home Developer Policies.
  3. You must open the Web OAuth linking page and ensure users have a clear method for signing in to their Google Account, such as fields for their username and password. Don't use the Google Sign-In (GSI) method that enables users to link without being taken to the Web OAuth Linking page. It is a violation of Google policy.
  4. You must include at least one of the following items in the OAuth linking page to indicate the integration to which the user is linking:
    • Company logo
    • Company name
    • Integration name
    • App icon

Recommendations

We recommend that you do the following:

  1. Display Google's Privacy Policy. Include a link to Google’s Privacy Policy on the consent screen.

  2. Data to be shared. Use clear and concise language to tell the user what data of theirs Google requires and why, and what usage or interaction data may be shared with you by Google.

  3. Clear call-to-action. State a clear call-to-action on your consent screen, such as “Agree and link.” This is because users need to understand what data they're required to share with Google to link their accounts.

  4. Ability to cancel. Provide a way for users to go back or cancel, if they choose not to link.

  5. Clear sign-in process. Ensure that users have a clear method for signing in to their Google Account, such as fields for their username and password or Sign in with Google.

  6. Ability to unlink. Offer a mechanism for users to unlink, such as a URL to their account settings on your platform. Alternatively, you can include a link to Google Account where users can manage their linked account. If a user unlinks from your integration, use agentUsers.delete to notify Google of the change.

  7. Ability to change user account. Suggest a method for users to switch their account(s). This is especially beneficial if users tend to have multiple accounts.

    • If a user must close the consent screen to switch accounts, send a recoverable error to Google so the user can sign in to the desired account with OAuth linking.
  8. Include your logo. Display your company logo on the consent screen. Use your style guidelines to place your logo. If you wish to also display Google's logo, see Logos and trademarks.

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

Реализация 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 соответствует идентификатору клиента, назначенному вами Google, а redirect_uri – URL переадресации, предоставленному Google для вашего сервиса. Эти проверки важны, чтобы предотвратить предоставление доступа непреднамеренным или неправильно настроенным клиентским приложениям. Если вы поддерживаете несколько потоков OAuth 2.0, убедитесь, что параметр response_type имеет значение code.
  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. При переадресации добавьте сгенерированный код авторизации и исходное значение параметра state, не изменяя его, с помощью параметров 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 следующим образом:

Перейти в Developer Console

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

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

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

  4. Прокрутите страницу вниз до раздела Разрешения (необязательно) и установите флажок Передавать идентификатор и секретный код клиента через заголовок базовой аутентификации 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. В теле ответа HTTPS верните следующий объект JSON:
    {
    "token_type": "Bearer",
    "access_token": "ACCESS_TOKEN",
    "refresh_token": "REFRESH_TOKEN",
    "expires_in": SECONDS_TO_EXPIRATION
    }

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

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

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

В этих запросах значение grant_type – refresh_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
    }

Handle userinfo requests

The userinfo endpoint is an OAuth 2.0 protected resource that return claims about the linked user. Implementing and hosting the userinfo endpoint is optional, except for the following use cases:

After the access token has been successfully retrieved from your token endpoint, Google sends a request to your userinfo endpoint to retrieve basic profile information about the linked user.

userinfo endpoint request headers
Authorization header The access token of type Bearer.

For example, if your userinfo endpoint is available at https://myservice.example.com/userinfo, a request might look like the following:

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

For your userinfo endpoint to handle requests, do the following steps:

  1. Extract access token from the Authorization header and return information for the user associated with the access token.
  2. If the access token is invalid, return an HTTP 401 Unauthorized error with using the WWW-Authenticate Response Header. Below is an example of a userinfo error response:
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: error="invalid_token",
    error_description="The Access Token expired"
    
    If a 401 Unauthorized, or any other unsuccessful error response is returned during the linking process, the error will be non-recoverable, the retrieved token will be discarded and the user will have to initiate the linking process again.
  3. If the access token is valid, return and HTTP 200 response with the following JSON object in the body of the HTTPS response:

    {
    "sub": "USER_UUID",
    "email": "EMAIL_ADDRESS",
    "given_name": "FIRST_NAME",
    "family_name": "LAST_NAME",
    "name": "FULL_NAME",
    "picture": "PROFILE_PICTURE",
    }
    If your userinfo endpoint returns an HTTP 200 success response, the retrieved token and claims are registered against the user's Google account.

    userinfo endpoint response
    sub A unique ID that identifies the user in your system.
    email Email address of the user.
    given_name Optional: First name of the user.
    family_name Optional: Last name of the user.
    name Optional: Full name of the user.
    picture Optional: Profile picture of the user.