Como lidar com permissões granulares

Visão geral

Com permissões granulares, os consumidores têm um controle mais preciso sobre quais dados da conta que escolhe compartilhar com cada aplicativo. Elas beneficiam usuários e desenvolvedores controle, transparência e segurança. Este guia vai ajudar você a entender as mudanças necessárias e as etapas para atualizar seus aplicativos e processar permissões granulares.

O que é permissão granular?

Imagine que você está desenvolvendo um app de produtividade que solicita escopos de e-mail e agenda. Seus usuários talvez você queira usar seu aplicativo apenas para o Google Agenda, mas não para o Gmail. Com OAuth granular do usuário, os usuários podem optar por dar permissão apenas ao Google Agenda, mas não ao Gmail. Ao permitir que os usuários concedam acesso a dados específicos, isso minimiza a exposição de dados, aumenta a confiança e oferece aos usuários o controle da vida digital com foco na privacidade. É importante projetar seu aplicativo para lidar com esses cenários.

Quando mais de um escopo que não seja de login é solicitado

Escopos de login e não de login

Nos aplicativos que solicitam escopos com e sem login, os usuários primeiro veem o consentimento. página para escopos de login. (email, profile e openid). Após os usuários consentirem com compartilharem informações básicas de identidade (nome, endereço de e-mail e foto de perfil), os usuários verão uma tela de consentimento de permissão granular para os escopos que não são de login. Nesse caso, o aplicativo deve verificar quais escopos são concedidos pelos usuários e não pode presumir que os usuários concedem todas as solicitações escopos. No exemplo a seguir, o aplicativo da Web solicita os três escopos de Login e um Escopo sem login do Google Drive. Depois que os usuários consentirem com os escopos de Login, vão aparecer Tela de consentimento de permissões granulares para a permissão do Google Drive:

Escopos com e sem login

Mais de um escopo que não é de login

Uma tela de consentimento de permissão granular seria exibida aos usuários quando os aplicativos solicitavam mais de um escopo que não seja de login. Os usuários podem selecionar quais permissões eles querem aprovar para compartilhar com o aplicativo. Confira a seguir um exemplo de tela de consentimento de permissão granular acesso às mensagens do Gmail e aos dados do Google Agenda dos usuários:

Mais de um escopo que não é de login

Para aplicativos que solicitam somente Login escopos (email, profile e openid), o escopo a tela de consentimento de permissões não é aplicável. Os usuários aprovam ou recusam todo o login solicitação. Ou seja, se os aplicativos solicitarem apenas escopos de Login (um, dois ou todos 3), a tela de consentimento de permissão granular não é aplicável.

Para aplicativos que solicitam apenas um escopo sem login, o escopo a tela de consentimento de permissão não é aplicável. Em outras palavras, os usuários aprovam ou negar toda a solicitação e não há caixa de seleção na tela de consentimento. A tabela a seguir resume quando a tela de consentimento de permissões granulares é exibida.

Número de escopos de Login Número de escopos que não são de login Tela de consentimento de permissões granular
1-3 0 Não relevante
1-3 1+ Aplicável
0 1 Não relevante
0 2+ Aplicável

Determinar se seus apps foram afetados

Faça uma análise completa de todas as seções do aplicativo em que Os endpoints de autorização do Google OAuth 2.0 são utilizados para solicitações de permissão. Preste atenção aqueles que solicitam vários escopos ao ativar telas de consentimento de permissão granulares apresentado aos usuários. Nesses casos, verifique se o código consegue processar apenas os casos em que os usuários autorizar alguns dos escopos.

Como determinar se um aplicativo está usando vários escopos

Inspecione o código do app ou a chamada de rede de saída para determinar se as solicitações de autorização do Google OAuth 2.0 feitas pelo app vão fazer com que a tela de consentimento de permissões granulares seja mostrada.

Inspecionar o código do aplicativo

Revise as seções do código do aplicativo em que você está fazendo chamadas para o serviço do Google OAuth endpoints de autorização para solicitar a permissão dos usuários. Se você usa uma das APIs do Google bibliotecas de cliente, muitas vezes é possível descobrir quais escopos seu aplicativo solicita no cliente etapas de inicialização. Alguns exemplos são mostrados na seção a seguir. Consulte a documentação dos SDKs usados pelo seu app para processar o Google OAuth 2.0 e determinar se o aplicativo é afetado, usando as orientações mostradas nos exemplos a seguir como referência.

Serviços de Identificação do Google

O snippet de código da biblioteca JavaScript dos Serviços de Identificação do Google a seguir inicializa o TokenClient com vários escopos que não são do Login do Google. A tela de permissão granular seria exibida quando a Web solicita autorização dos usuários.

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly \
  https://www.googleapis.com/auth/contacts.readonly',
  callback: (response) => {
    ...
  },
});

Python

O snippet de código a seguir usa o módulo google-auth-oauthlib.flow para e cria a solicitação de autorização. O parâmetro scope inclui duas escopos sem login. A tela de permissão granular seria exibida quando a Web o aplicativo solicita a autorização dos usuários.

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Use the client_secret.json file to identify the application requesting
# authorization. The client ID (from that file) and access scopes are required.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/calendar.readonly',
                    'https://www.googleapis.com/auth/contacts.readonly'])

Node.js

O snippet de código abaixo cria um objeto google.auth.OAuth2, que define a na solicitação de autorização cujo parâmetro scope inclui dois parâmetros escopos sem login. A tela de permissão granular apareceria quando o app da Web solicita autorização dos usuários.

const {google} = require('googleapis');

/**
  * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
  * from the client_secret.json file. To get these credentials for your application, visit
  * https://console.cloud.google.com/apis/credentials.
  */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Calendar and Contacts.
const scopes = [
  'https://www.googleapis.com/auth/calendar.readonly',
  'https://www.googleapis.com/auth/contacts.readonly']
];

// Generate a url that asks permissions
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true
});

Inspecionar a chamada de rede realizada

O método de inspeção de chamadas de rede varia de acordo com o tipo de cliente de aplicativo.

Ao inspecionar as chamadas de rede, procure solicitações enviadas aos endpoints de autorização do Google OAuth e examine o parâmetro scope.

Esses valores fazem a exibição da tela de consentimento de permissões granulares.

  • O parâmetro scope contém escopos de login e não de login.

    O exemplo de solicitação a seguir contém os três escopos de Login e um escopo que não é de login para visualizar os metadados dos arquivos do usuário no Google Drive:

    https://accounts.google.com/o/oauth2/v2/auth?
    access_type=offline&
    scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
    include_granted_scopes=true&
    response_type=code&
    redirect_uri=YOUR_REDIRECT_URL&
    client_id=YOUR_CLIENT_ID
  • O parâmetro scope contém mais de um escopo que não é de login.

    O exemplo de solicitação a seguir contém dois escopos que não são de login para visualizar o Google Drive do usuário metadados e gerenciar arquivos específicos do Google Drive:

  • https://accounts.google.com/o/oauth2/v2/auth?
    access_type=offline&
    scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&
    include_granted_scopes=true&
    response_type=code&
    redirect_uri=YOUR_REDIRECT_URL&
    client_id=YOUR_CLIENT_ID

Práticas recomendadas para lidar com permissões granulares

Se você determinar que seu aplicativo precisa ser atualizado para lidar permissões granulares, você deve fazer as atualizações necessárias em seu código para lidar corretamente com o consentimento para vários escopos. Todos os aplicativos precisam seguir as práticas recomendadas abaixo:

  1. Revise a Serviços de API do Google: política de dados do usuário e verifique se você está em conformidade com ela.
  2. Solicite escopos específicos necessários para uma tarefa. Você precisa obedecer à política do Google OAuth 2.0 de que só solicite escopos que sejam necessários. Evite pedir vários escopos no login, a menos que isso seja essencial para a funcionalidade principal do app. Agrupar vários escopos, especialmente para usuários que não estão familiarizados com os recursos do aplicativo, pode dificultar a compreensão da necessidade dessas permissões. Isso pode gerar alarmes e impedir que os usuários interajam mais com o para o aplicativo.
  3. Forneça uma justificativa aos usuários antes de fazer o solicitação de autorização. Explique claramente por que seu aplicativo precisa da permissão solicitada. o que você fará com os dados do usuário e como o usuário se beneficiará com a aprovação da solicitação. Nossa pesquisa indica que essas explicações aumentam a confiança e o engajamento dos usuários.
  4. Uso autorização incremental sempre que seu aplicativo solicitar escopos para evitar ter que gerenciar múltiplos tokens de acesso.
  5. Verifique quais escopos os usuários concederam. Ao solicitar várias escopos de uma só vez, talvez os usuários não concedam todos os escopos às solicitações do seu aplicativo. Seu app deve sempre verifica quais escopos foram concedidos pelo usuário e lida com as recusas de escopos ao desabilitar atributos de machine learning. Siga as políticas do Google OAuth 2.0 sobre como processar o consentimento para vários escopos e só solicite o consentimento do usuário novamente quando ele indicar claramente a intenção de usar o recurso específico que exige o escopo.

Atualizar o aplicativo para processar permissões granulares

Aplicativos Android

Consulte a documentação dos SDKs que você usa para interagir com o Google OAuth 2.0 e atualize seu app para processar permissões granulares com base nas práticas recomendadas.

Se você usar auth.api.signin SDK do Google Play Services para interagir com o Google OAuth 2.0, é possível usar requestPermissions para solicitar o menor conjunto de escopos necessários, e o hasPermissions para verificar quais escopos o usuário concedeu quando solicitando permissões granulares.

Aplicativos com extensão do Chrome

Você deve usar Google Chrome Identity para funcionar com o Google OAuth 2.0 com base no práticas recomendadas.

O exemplo a seguir mostra como processar permissões granulares corretamente.

manifest.json

O arquivo de manifesto de exemplo declara dois escopos que não são de login para o aplicativo de extensão do Chrome.

{
  "name": "Example Chrome extension application",
  ...
  "permissions": [
      "identity"
    ],
  "oauth2" : {
      "client_id": "YOUR_CLIENT_ID",
      "scopes":["https://www.googleapis.com/auth/calendar.readonly",
                "https://www.googleapis.com/auth/contacts.readonly"]
  }
}

Abordagem incorreta

Tudo ou nada

Os usuários clicam nesse botão para iniciar o processo de autorização. O snippet de código pressupõe que os usuários recebem uma tela de consentimento "tudo ou nada" para os dois escopos especificados no arquivo manifest.json. Ela não verifica quais escopos foram concedidos pelos usuários.

oauth.js

...
document.querySelector('button').addEventListener('click', function () {
  chrome.identity.getAuthToken({ interactive: true },
      function (token) {
          if (token === undefined) {
            // User didn't authorize both scopes.
            // Updating the UX and application accordingly
            ...
          } else {
            // User authorized both or one of the scopes.
            // It neglects to check which scopes users granted and assumes users granted all scopes.

            // Calling the APIs, etc.
            ...
          }
      });
});

Abordagem correta

Escopos menores

Selecione o menor conjunto de escopos necessário

O aplicativo deve solicitar apenas o menor conjunto de escopos necessários. É recomendado que seu aplicativo solicite um escopo por vez quando for necessário para concluir uma tarefa.

Neste exemplo, supõe-se que ambos os escopos declarados no manifest.json são o menor conjunto de escopos necessários. O arquivo oauth.js usa o Chrome Identity para iniciar o processo de autorização com o Google. Você deve ativar ativar permissões granulares para que os usuários tenham mais controle ao conceder permissões. para o aplicativo. Seu aplicativo deve lidar corretamente com a resposta dos usuários verificando escopos autorizados pelos usuários.

oauth.js

...
document.querySelector('button').addEventListener('click', function () {
  chrome.identity.getAuthToken({ interactive: true, enableGranularPermissions: true },
      function (token, grantedScopes) {
          if (token === undefined) {
            // User didn't authorize any scope.
            // Updating the UX and application accordingly
            ...
          } else {
            // User authorized the request. Now, check which scopes were granted.
            if (grantedScopes.includes('https://www.googleapis.com/auth/calendar.readonly'))
            {
              // User authorized Calendar read permission.
              // Calling the APIs, etc.
              ...
            }
            else
            {
              // User didn't authorize Calendar read permission.
              // Update UX and application accordingly
              ...
            }

            if (grantedScopes.includes('https://www.googleapis.com/auth/contacts.readonly'))
            {
              // User authorized Contacts read permission.
              // Calling the APIs, etc.
              ...
            }
            else
            {
              // User didn't authorize Contacts read permission.
              // Update UX and application accordingly
              ...
            }
          }
      });
});

Aplicativos iOS, iPadOS e macOS

Consulte a documentação dos SDKs que você usa para interagir com o Google OAuth 2.0 e atualize seu app para processar permissões granulares com base nas práticas recomendadas.

Se você usa a biblioteca do Login do Google para iOS e macOS interagir com o Google OAuth 2.0, consulte a documentação sobre processamento de dados permissões.

Aplicativos da Web

Consulte a documentação dos SDKs que você usa para interagir com o Google OAuth 2.0 e atualize seu app para processar permissões granulares com base nas práticas recomendadas.

Acesso do lado do servidor (off-line)

O modo de acesso do lado do servidor (off-line) exige que você faça o seguinte:
  • Configure um servidor e defina um endpoint acessível publicamente para receber o código de autorização.
  • Configure o URI de redirecionamento do endpoint público no do console do Google Cloud.

O snippet de código a seguir mostra um exemplo de NodeJS que solicita dois escopos que não são de login. Os usuários vão conferir a tela de consentimento de permissão granular.

Abordagem incorreta

Tudo ou nada

Os usuários são redirecionados ao URL de autorização. O snippet de código presume que os usuários são apresentados com uma abordagem de "tudo ou nada" tela de consentimento para os dois escopos especificados destino de scopes. Ela não verifica quais escopos foram concedidos pelos usuários.

main.js

...
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
  'https://www.googleapis.com/auth/contacts.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a url that asks permissions for the Google Calendar and Contacts scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // Pass in the scopes array defined above
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true
});

async function main() {
  const server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }
    // Receive the callback from Google OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the Google OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) {
        // User didn't authorize both scopes.
        // Updating the UX and application accordingly
        ...
      } else {
        // User authorized both or one of the scopes.
        // It neglects to check which scopes users granted and assumes users granted all scopes.

        // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        // Calling the APIs, etc.
        ...
      }
    }
    res.end();
  }).listen(80);
}
Abordagem correta

Menor escopo

Selecione o menor conjunto de escopos necessário

O aplicativo deve solicitar apenas o menor conjunto de escopos necessários. É recomendado que seu aplicativo solicite um escopo por vez quando for necessário para concluir uma tarefa. Sempre que o aplicativo solicitar escopos, ele vai usar autorização incremental para evitar o gerenciamento de vários tokens de acesso.

Se o aplicativo precisar solicitar vários escopos que não sejam de login, sempre use autorização incremental ao fazer a solicitação e verifique quais escopos os usuários concederam.

Neste exemplo, supomos que ambos os escopos declarados são necessários para que o aplicativo funcione corretamente. Você deve ativar ativar permissões granulares para que os usuários tenham mais controle ao conceder permissões. para o aplicativo. Seu aplicativo deve lidar corretamente com a resposta dos usuários verificando os escopos autorizados.

main.js

...
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
  'https://www.googleapis.com/auth/contacts.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a url that asks permissions for the Google Calendar and Contacts scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // Pass in the scopes array defined above
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true,
  // Set to true to enable more granular permissions for Google OAuth 2.0 client IDs created before 2019.
  // No effect for newer Google OAuth 2.0 client IDs, since more granular permissions is always enabled for them.
  enable_granular_consent: true
});

async function main() {
  const server = http.createServer(async function (req, res) {
    // Redirect users to Google OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }
    // Receive the callback from Google OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the Google OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) {
        // User didn't authorize both scopes.
        // Updating the UX and application accordingly
        ...
      } else {
        // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        oauth2Client.setCredentials(tokens);

        // User authorized the request. Now, check which scopes were granted.
        if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
        {
          // User authorized Calendar read permission.
          // Calling the APIs, etc.
          ...
        }
        else
        {
          // User didn't authorize Calendar read permission.
          // Calling the APIs, etc.
          ...
        }

        // Check which scopes user granted the permission to application
        if (tokens.scope.includes('https://www.googleapis.com/auth/contacts.readonly'))
        {
          // User authorized Contacts read permission.
          // Calling the APIs, etc.
          ...
        }
        else
        {
          // User didn't authorize Contacts read permission.
          // Update UX and application accordingly
          ...
        }
      }
    }
    res.end();
  }).listen(80);
}

Analise o guia do app da Web do lado do servidor sobre como acessar as APIs do Google a partir de aplicativos baseados em servidor.

Acesso somente do lado do cliente

  • Para aplicativos que usam os Serviços de Identificação do Google para interagir com o Google OAuth 2.0. Consulte este documentação sobre como lidar com permissões granulares.
  • Para aplicativos que fazem chamadas diretamente usando JavaScript para endpoints de autorização do OAuth 2.0 do Google, consulte esta documentação sobre como processar permissões granulares.

Testar o aplicativo atualizado no processamento de permissões granulares

  1. Descreva todos os casos em que os usuários podem responder a solicitações de permissão e os comportamento esperado do seu aplicativo. Por exemplo, se o usuário autorizar somente dois de três escopos solicitados, seu aplicativo deve se comportar de forma adequada.
  2. Teste seu aplicativo com a permissão granular ativada. Há duas maneiras de ativar permissões granulares:
    1. Verifique as telas de consentimento do OAuth 2.0 do seu aplicativo para ver se permissões granulares já estão ativadas para sua para o aplicativo. Também é possível criar um novo ID do cliente do Google OAuth 2.0 para Web, Android ou iOS. pelo console do Google Cloud para fins de teste, já que a permissão granular é sempre ativado para eles.
    2. Defina o parâmetro enable_granular_consent como true ao chamar os endpoints de autorização OAuth do Google. Alguns SDKs têm suporte explícito para isso . Para outros, consulte a documentação para saber como adicionar esse parâmetro e o valor dele manualmente. Se a sua implementação não oferecer suporte à adição do parâmetro, crie um novo ID do cliente do Google OAuth 2.0 para Web, Android ou iOS pelo console do Google Cloud apenas para fins de teste, conforme indicado no ponto anterior.
  3. Ao testar seu aplicativo atualizado, use uma Conta do Google pessoal (@gmail.com) em vez de uma conta do Workspace. Isso acontece porque os apps do Workspace Enterprise com delegação de autoridade em todo o domínio ou marcada como Confiável não são afetadas pelas alterações nas permissões granulares no momento. Portanto, testar com um Workspace da sua organização pode não mostrar a nova tela de consentimento granular como pretendido.