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

Каждое Действие smart home должно включать в себя механизм аутентификации пользователей.

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

На этой странице описано, как настроить сервер OAuth 2.0, чтобы он работал с действием вашего smart home .

Привязка аккаунта Google с помощью OAuth

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 provide a way for users to go back or cancel, if they choose not to link.
  4. 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.

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.

  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 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.

  5. 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.
  6. 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 .
user_locale Языковой параметр учетной записи Google в формате RFC5646 , используемый для локализации вашего контента на предпочитаемом пользователем языке.

Например, если ваша конечная точка авторизации доступна по адресу 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&user_locale=LOCALE

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

  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 . Включите только что сгенерированный код авторизации и исходное неизмененное значение состояния при перенаправлении, добавив параметры 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 отправляет запрос на вашу конечную точку обмена токенами, чтобы обменять код авторизации на токен доступа и токен обновления.

Для этих запросов значение 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 для получения основной информации профиля о связанном пользователе.

Заголовки запроса конечной точки 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
    sub Уникальный идентификатор, который идентифицирует пользователя в вашей системе.
    email Адрес электронной почты пользователя.
    given_name Необязательно: Имя пользователя.
    family_name Необязательно: Фамилия пользователя.
    name Необязательно: Полное имя пользователя.
    picture Необязательно: изображение профиля пользователя.