Vinculação da Conta do Google com o OAuth

As contas são vinculadas usando os fluxos implícitos e de código de autorização do OAuth 2.0 padrão do setor. Seu serviço precisa oferecer suporte a endpoints de autorização e troca de token compatíveis com o OAuth 2.0.

隐式流程中,Google 会在用户的浏览器中打开您的授权端点。成功登录后,您将向 Google 返回一个长期访问令牌。现在,此访问令牌会包含在 Google 发送的每个请求中。

授权代码流程中,您需要两个端点:

  • 授权端点,用于向尚未登录的用户显示登录界面。授权端点还会创建一个短期授权代码,以记录用户对所请求访问权限的同意情况。

  • 令牌交换端点,负责两种类型的交换:

    1. 使用授权代码换取长期有效的刷新令牌和短期有效的访问令牌。当用户完成账号关联流程时,就会发生此交换。
    2. 将长期有效的刷新令牌换成短期有效的访问令牌。当 Google 需要新的访问令牌(因为现有访问令牌已过期)时,就会发生这种交换。

选择 OAuth 2.0 流程

虽然隐式流程更易于实现,但 Google 建议通过隐式流程签发的访问令牌永不过期。这是因为,在隐式流程中,令牌过期后,系统会强制用户重新关联其账号。如果您出于安全考虑需要令牌过期,我们强烈建议您改用授权码流程。

设计准则

本部分介绍了您为 OAuth 关联流程托管的用户屏幕的设计要求和建议。在 Google 应用调用该 API 后,您的平台会向用户显示登录 Google 页面和账号关联意见征求界面。同意关联账号后,系统会将用户重定向回 Google 的应用。

此图展示了用户将其 Google 账号与您的身份验证系统相关联的步骤。第一个屏幕截图显示了用户从您的平台发起的关联。第二张图片显示用户登录 Google,第三张图片显示用户同意并确认将其 Google 账号与您的应用相关联。最后一张屏幕截图显示 Google 应用中成功关联的用户账号。
图 1.账号关联用户登录 Google 和同意屏幕。

要求

  1. 您必须说明用户的账号将与 Google 相关联,而非 Google Home 或 Google 助理等特定 Google 产品相关联。

建议

建议您执行以下操作:

  1. 显示 Google 的隐私权政策。在同意屏幕上添加指向 Google 隐私权政策的链接。

  2. 要共享的数据。使用清晰简洁的语言告知用户 Google 需要哪些用户数据以及原因。

  3. 添加醒目的号召性用语。在用户同意页面上提供明确的号召性用语,例如“同意并关联”。这是因为用户需要了解他们需要与 Google 分享哪些数据才能关联账号。

  4. 可以取消。为用户提供返回或取消链接的途径,如果用户选择不进行关联。

  5. 明确的登录流程。确保用户有明确的 Google 账号登录方法,例如用户名和密码字段或使用 Google 账号登录

  6. 能够解除关联。提供一种可让用户解除关联的机制,例如指向您平台上账号设置的网址。或者,您也可以添加指向 Google 账号的链接,以便用户管理其关联的账号。

  7. 能够更改用户账号。建议用户切换账号的方法。如果用户通常拥有多个账号,这种做法尤为有益。

    • 如果用户必须关闭意见征求界面才能切换账号,请向 Google 发送可恢复的错误,以便用户可以使用 OAuth 关联隐式流程登录所需的账号。
  8. 添加您的徽标。在意见征求页面上显示您的公司徽标。 按照您的样式准则放置徽标。如果您还想显示 Google 的徽标,请参阅徽标和商标

创建项目

如需创建项目以使用账号关联功能,请执行以下操作:

Google 账号关联流程包含一个权限请求页面,用于告知用户请求访问其数据的应用、应用请求访问的数据类型以及适用的条款。您需要先配置 OAuth 权限请求页面,然后才能生成 Google API 客户端 ID。

  1. 打开 Google API 控制台的 OAuth 同意屏幕页面。
  2. 如果出现提示,请选择您刚刚创建的项目。
  3. 在“OAuth 同意屏幕”页面上,填写表单,然后点击“保存”按钮。

    应用名称:征求用户同意的应用的名称。该名称应准确反映您的应用,并与用户在其他地方看到的应用名称一致。应用名称将显示在账号关联意见征求界面上。

    应用徽标:权限请求页面上显示的一张图片,用以让用户认出您的应用。该徽标会显示在账号关联意见征求页面和账号设置

    支持电子邮件:供用户就其是否同意的问题与您联系。

    Google API 的范围:借助范围,您的应用可以访问用户的私密 Google 数据。对于 Google 账号关联用例,默认范围(电子邮件地址、个人资料、openid)已足够,您无需添加任何敏感范围。通常,最佳做法是在需要访问权限时逐步请求相应权限范围,而不是提前请求。了解详情

    已获授权的网域:为了保护您和您的用户,Google 只允许使用 OAuth 进行身份验证的应用使用已获授权的网域。您应用的链接必须托管在已获授权的网域上。了解详情

    应用首页链接:应用的首页。必须托管在已获授权的网域上。

    应用隐私权政策链接:显示在 Google 账号关联意见征求界面上。必须托管在已获授权的网域上。

    应用服务条款链接(可选):必须托管在已获授权的网域上。

    图 1. 虚构应用 Tunery 的 Google 账号关联意见征求界面

  4. 查看“验证状态”,如果您的应用需要验证,请点击“提交以供验证”按钮,以提交您的应用以供验证。如需了解详情,请参阅 OAuth 验证要求

Implementar seu servidor OAuth

Uma implementação do servidor OAuth 2.0 do fluxo do código de autorização consiste em: dois endpoints, que seu serviço disponibiliza por HTTPS. O primeiro endpoint é o endpoint de autorização, responsável por encontrar ou conseguir o consentimento dos usuários para acesso aos dados. O endpoint de autorização apresenta uma interface de login para os usuários que ainda não estão conectados e registra o consentimento para o acesso solicitado. O segundo endpoint é a troca de tokens, é usado para obter strings criptografadas, chamadas de tokens, que autorizam um usuário a para acessar seu serviço.

Quando um aplicativo do Google precisa chamar uma das APIs do seu serviço, o Google usa esses endpoints juntos para conseguir a permissão dos usuários para chamar essas APIs em nome deles.

Uma sessão do fluxo do código de autorização do OAuth 2.0 iniciada pelo Google tem seguinte fluxo:

  1. O Google abre seu endpoint de autorização no navegador do usuário. Se o fluxo iniciada em um dispositivo somente de voz para uma ação, o Google transfere a execução em um smartphone.
  2. Caso ainda não tenha feito login, o usuário faz login e concede ao Google permissão para acessar os dados com a API, caso ainda não tenham concedido permissão.
  3. Seu serviço cria um código de autorização e o retorna ao Google. Afazeres Por isso, redirecione o navegador do usuário de volta para o Google com o código de autorização anexada à solicitação.
  4. O Google envia o código de autorização para seu endpoint de troca de token, verifica a autenticidade do código e retorna um token de acesso e um token de atualização. O token de acesso é um token de curta duração que seu serviço aceita como credenciais para acessar APIs. O token de atualização é um token de atualização token que o Google pode armazenar e usar para adquirir novos tokens de acesso e depois ela expira.
  5. Depois que o usuário tiver concluído o fluxo de vinculação à conta, todas as solicitação enviada pelo Google contém um token de acesso.

Processar solicitações de autorização

Quando você precisa vincular a conta usando o código de autorização do OAuth 2.0. fluxo, o Google envia o usuário para seu endpoint de autorização com uma solicitação que inclui os seguintes parâmetros:

Parâmetros de endpoint de autorização
client_id O Client-ID que você atribuiu ao Google.
redirect_uri O URL para o qual você envia a resposta para essa solicitação.
state Um valor de contabilidade que é retornado ao Google inalterado na URI de redirecionamento.
scope Opcional:um conjunto delimitado por espaços de strings de escopo que especifica o dados para os quais o Google está solicitando autorização.
response_type O tipo de valor a ser retornado na resposta. Para a solicitação OAuth 2.0, fluxo do código de autorização, o tipo de resposta será sempre code.
user_locale A configuração de idioma da Conta do Google no RFC5646 usado para localizar seu conteúdo no idioma de preferência do usuário.

Por exemplo, se o endpoint de autorização estiver disponível em https://myservice.example.com/auth, uma solicitação terá esta aparência:

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

Para que o endpoint de autorização processe solicitações de login, faça o seguinte: etapas:

  1. Verifique se o client_id corresponde ao ID do cliente atribuído ao Google e se o redirect_uri corresponde ao URL de redirecionamento fornecido pelo Google para seu serviço. Essas verificações são importantes para impedir a concessão o acesso a apps clientes não intencionais ou configurados incorretamente. Se você oferece suporte a vários Fluxos do OAuth 2.0. Confirme também se o response_type é code.
  2. Verifique se o usuário está conectado ao seu serviço. Se o usuário não estiver conectado, para concluir o fluxo de login ou inscrição do serviço.
  3. Gere um código de autorização para o Google usar no acesso à API. O código de autorização pode ser qualquer valor de string, mas deve ser representar o usuário, o cliente a que o token se destina e a expiração do código tempo de resposta e não deve ser adivinhado. Você normalmente emite uma autorização que expiram após aproximadamente 10 minutos.
  4. Confirme se o URL especificado pelo parâmetro redirect_uri tem o seguinte formato:
      https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID
      https://oauth-redirect-sandbox.googleusercontent.com/r/YOUR_PROJECT_ID
      
  5. Redirecione o navegador do usuário para o URL especificado pelo parâmetro redirect_uri. Inclua o código de autorização que você e o valor do estado original e inalterado ao redirecionar anexando os parâmetros code e state. Confira a seguir exemplo do URL resultante:
    https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID?code=AUTHORIZATION_CODE&state=STATE_STRING

Processar solicitações de troca de token

O endpoint de troca de token do seu serviço é responsável por dois tipos de token trocas:

  • Trocar códigos de autorização por tokens de acesso e de atualização
  • Trocar tokens de atualização por tokens de acesso

As solicitações de troca de token incluem os seguintes parâmetros:

Parâmetros de endpoint de troca de token
client_id Uma string que identifica a origem da solicitação como o Google. Essa string precisa ser registrado em seu sistema como identificador exclusivo do Google.
client_secret Uma string secreta que você registrou no Google para seu serviço.
grant_type O tipo de token que está sendo trocado. É authorization_code ou refresh_token.
code Quando grant_type=authorization_code, esse parâmetro é o O código que o Google recebeu do seu login ou da troca de tokens endpoint do Google Cloud.
redirect_uri Quando grant_type=authorization_code, esse parâmetro é o URL usado na solicitação de autorização inicial.
refresh_token Quando grant_type=refresh_token, esse parâmetro é o token de atualização que o Google recebeu de seu endpoint de troca de token.
Trocar códigos de autorização por tokens de acesso e de atualização

Depois que o usuário fizer login e o endpoint de autorização retornar um endereço de e-mail código de autorização ao Google, ele envia uma solicitação à troca de token para trocar o código de autorização por um token de acesso e uma atualização com base no token correto anterior.

Para essas solicitações, o valor de grant_type é authorization_code, e a o valor de code é o valor do código de autorização concedido anteriormente para o Google. Veja a seguir um exemplo de solicitação para trocar um código de autorização para um token de acesso e um token de atualização:

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

Para trocar códigos de autorização por um token de acesso e um token de atualização, seu endpoint de troca de token responde a solicitações POST executando o seguinte etapas:

  1. Verifique se client_id identifica a origem da solicitação como origem e se o client_secret corresponde ao valor esperado.
  2. Verifique se o código de autorização é válido e não expirou, e se o ID do cliente especificado na solicitação corresponde ao ID do cliente associado à código de autorização.
  3. Confirme se o URL especificado pelo parâmetro redirect_uri é idêntico ao valor usado na solicitação de autorização inicial.
  4. Se não for possível verificar todos os critérios acima, retorne uma solicitação HTTP Erro 400 Solicitação inválida com {"error": "invalid_grant"} como o corpo.
  5. Caso contrário, use o ID do usuário do código de autorização para gerar uma atualização e um token de acesso. Esses tokens podem ser de qualquer valor de string, devem representar exclusivamente o usuário e o cliente a que o token se destina, e elas não pode ser adivinhado. Para tokens de acesso, registre também o tempo de expiração o token, que normalmente é uma hora após a emissão do token. Os tokens de atualização não expiram.
  6. Retorne o seguinte objeto JSON no corpo da resposta HTTPS:
    {
    "token_type": "Bearer",
    "access_token": "ACCESS_TOKEN",
    "refresh_token": "REFRESH_TOKEN",
    "expires_in": SECONDS_TO_EXPIRATION
    }

O Google armazena os tokens de acesso e de atualização do usuário e dos registros a expiração do token de acesso. Quando o token de acesso expira, o Google usa o token de atualização para receber um novo token de acesso do endpoint de troca de tokens.

Trocar tokens de atualização por tokens de acesso

Quando um token de acesso expira, o Google envia uma solicitação à troca de tokens endpoint para trocar um token de atualização por um novo token de acesso.

Para essas solicitações, o valor de grant_type é refresh_token, e o valor de refresh_token é o valor do token de atualização concedido anteriormente para Google. Este é um exemplo de solicitação para trocar um token de atualização para um token de acesso:

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

Para trocar um token de atualização por um de acesso, o endpoint de troca de token responde a solicitações POST executando as seguintes etapas:

  1. Verifique se client_id identifica a origem da solicitação como Google. se o client_secret corresponde ao valor esperado.
  2. Verifique se o token de atualização é válido e se o ID do cliente especificado em a solicitação corresponde ao ID do cliente associado ao token de atualização.
  3. Se não for possível verificar todos os critérios acima, retorne um erro HTTP 400 Erro de solicitação inválido com {"error": "invalid_grant"} como o corpo.
  4. Caso contrário, use o ID de usuário do token de atualização para gerar um acesso com base no token correto anterior. Esses tokens podem ser de qualquer valor de string, mas devem ser representam o usuário e o cliente a que o token se destina, e eles não devem ser pode ser adivinhado. Para tokens de acesso, registre também o tempo de expiração do token. geralmente uma hora após a emissão do token.
  5. Retorne o seguinte objeto JSON no corpo da solicitação resposta:
    {
    "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.

Como validar a implementação

您可以使用 OAuth 2.0 Playground 工具验证您的实现。

在该工具中,执行以下步骤:

  1. 点击配置 以打开 OAuth 2.0 配置窗口。
  2. OAuth flow 字段中,选择 Client-side(客户端)。
  3. OAuth 端点字段中,选择自定义
  4. 在相应字段中指定您的 OAuth 2.0 端点和您分配给 Google 的客户端 ID。
  5. 第 1 步部分,不要选择任何 Google 范围。请将此字段留空或输入对服务器有效的范围(如果您不使用 OAuth 范围,则可以输入任意字符串)。完成后,点击授权 API
  6. Step 2Step 3 部分中,完成 OAuth 2.0 流程,并验证每个步骤是否按预期运行。

您可以使用 Google 账号关联演示版工具验证您的实现。

在该工具中,执行以下步骤:

  1. 点击使用 Google 账号登录按钮。
  2. 选择您要关联的账号。
  3. 输入服务 ID。
  4. (可选)输入您要请求访问权限的一个或多个范围。
  5. 点击开始演示
  6. 当系统提示时,请确认您同意或拒绝关联请求。
  7. 确认您已被重定向到您的平台。