Como enviar uma solicitação autenticada de um aplicativo em JavaScript

Nesta página, você verá como enviar uma solicitação autenticada de um aplicativo em JavaScript executado localmente para uma API REST criada com o Cloud Endpoints Frameworks. O aplicativo em JavaScript mostra como usar o Login do Google e enviar um token de código do Google na solicitação para autenticar o usuário. Quando o aplicativo em JavaScript envia a solicitação, o Endpoints Frameworks autentica o usuário antes de transmitir a solicitação para o código de back-end que está em execução no ambiente padrão do App Engine.

Prerequisites

Para executar o aplicativo em JavaScript de amostra:

  • Encontre o ID do projeto do Google Cloud que você criou para a API de amostra, porque é necessário adicioná-lo ao código JavaScript de exemplo. Se precisar de ajuda para encontrar o ID do projeto, consulte Como listar projetos.

  • É necessário um servidor da Web no computador local para exibir o arquivo index.html de amostra que contém o código JavaScript. Nesta página, mostramos as etapas para executar um servidor simples usando o Python, mas é possível usar qualquer servidor da Web.

Fazer o download do código do cliente JavaScript de amostra

  1. Clone a amostra na máquina local:

    git clone https://github.com/GoogleCloudPlatform/web-docs-samples
    
  2. Mude para o diretório que contém o cliente JavaScript:

    cd web-docs-samples/endpoints-frameworks
    

Como criar IDs do cliente OAuth 2.0

Para configurar a amostra para autenticação, configure um ID do cliente do OAuth 2.0 no código JavaScript de amostra e no código de back-end. O aplicativo JavaScript usa o ID do cliente para conseguir um token de ID do Google do servidor OAuth 2.0 do Google e o envia na solicitação. O Endpoints Frameworks usa o ID do cliente para autenticar o token de ID que o app JavaScript enviou na solicitação.

Para criar um ID do cliente:

  1. No Console do Google Cloud, acesse a página "Credenciais".

    Acessar a página "Credenciais"

  2. Na lista de projetos, selecione o projeto criado para a API de amostra.

  3. Clique no botão Criar credenciais e selecione ID do cliente OAuth. Se esta for a primeira vez que você cria um ID do cliente neste projeto, use as subetapas para definir um nome de produto na tela de consentimento. Caso contrário, pule para a próxima etapa.

    1. Clique no botão Configurar tela de consentimento.
    2. Digite um nome no campo Nome do aplicativo.
    3. Clique em Save.
  4. Em Tipo de aplicativo, clique em Aplicativo da Web.

  5. No campo Origens JavaScript autorizadas, insira o seguinte:

    http://localhost:8080
    
  6. Clique em Criar.

  7. Copie seu ID do cliente. O ID do cliente completo é semelhante ao seguinte, mas é exclusivo para o aplicativo da Web no projeto.

    271473851874-mtll5dk2vultovbtilt31hakqbinpuvd.apps.googleusercontent.com

Para mais informações sobre como criar IDs de clientes, consulte Como configurar o OAuth 2.0.

Como configurar o código de back-end e reimplantar

Para que o Cloud Endpoints Frameworks autentique a solicitação enviada do aplicativo em JavaScript, é preciso adicionar o ID do cliente recém-criado ao código de amostra e reimplantar um documento do OpenAPI atualizado e o código de back-end do aplicativo.

O procedimento a seguir pressupõe que você já implantou a API de amostra em Primeiros passos com o Endpoints Frameworks para Java. Antes de iniciar o procedimento, verifique se você recebe uma resposta bem-sucedida ao enviar uma solicitação para a API, conforme descrito em Como enviar uma solicitação à API.

Para configurar o código de back-end e reimplantar:

  1. No diretório em que você clonou o repositório java-docs-samples, mude para o diretório que contém a amostra de Java:

    cd YOUR_WORKING_DIRECTORY/java-docs-samples/appengine-java8/endpoints-v2-backend
    
  2. Abra o arquivo src/main/java/com/example/echo/Echo.java em um editor de texto.

  3. Na anotação @ApiMethod do método getUserEmail, substitua YOUR_OAUTH_CLIENT_ID nos atributos audiences e clientIds pelo ID do cliente criado.

    @ApiMethod(
        httpMethod = ApiMethod.HttpMethod.GET,
        authenticators = {EspAuthenticator.class},
        audiences = {"YOUR_OAUTH_CLIENT_ID"},
        clientIds = {"YOUR_OAUTH_CLIENT_ID"}
    )
    public Email getUserEmail(User user) throws UnauthorizedException {
      if (user == null) {
        throw new UnauthorizedException("Invalid credentials");
      }
    
      Email response = new Email();
      response.setEmail(user.getEmail());
      return response;
    }
  4. Salve o arquivo Echo.java.

  5. Limpe o projeto e crie a API:

    Maven

    mvn clean package

    Gradle

          gradle clean
          gradle build
  6. Gere novamente o documento OpenAPI openapi.json para que ele contenha o ID do cliente.

    Maven

    mvn endpoints-framework:openApiDocs

    Gradle

    gradle endpointsOpenApiDocs
  7. Verifique se a CLI do Google Cloud (gcloud) está autorizada a acessar seus dados e serviços no Google Cloud:

    gcloud auth login
    
  8. Defina o projeto padrão da CLI do Google Cloud. Substitua YOUR_PROJECT_ID pelo ID do projeto criado para a API de amostra:

    gcloud config set project YOUR_PROJECT_ID
    
  9. Implante o documento da OpenAPI atualizado:

    gcloud endpoints services deploy target/openapi-docs/openapi.json
    
  10. Aguarde a conclusão do comando e implante o aplicativo novamente:

    Maven

    mvn appengine:deploy

    Gradle

    gradle appengineDeploy

Como configurar o código JavaScript

Para configurar o código JavaScript:

  1. No diretório web-docs-samples/endpoints-frameworks, abra o arquivo main.js em um editor de texto.
  2. Na função initGoogleAuth, substitua YOUR_CLIENT_ID pelo ID do cliente que você criou.

    function initGoogleAuth (clientId = 'YOUR_CLIENT_ID') {
      gapi.auth2.init({
        client_id: clientId,
        scope: 'https://www.googleapis.com/auth/userinfo.email'
      }).then(() => {
        document.getElementById('sign-in-btn').disabled = false;
      }).catch(err => {
        console.log(err);
      });
    }
  3. Na função sendSampleRequest, substitua YOUR_PROJECT_ID pelo ID do projeto criado para a API de amostra.

    function sendSampleRequest (projectId = 'YOUR_PROJECT_ID') {
      var user = gapi.auth2.getAuthInstance().currentUser.get();
      var idToken = user.getAuthResponse().id_token;
      var endpoint = `https://${projectId}.appspot.com/_ah/api/echo/v1/email`;
      var xhr = new XMLHttpRequest();
      xhr.open('GET', endpoint + '?access_token=' + encodeURIComponent(idToken));
      xhr.onreadystatechange = function () {
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
          window.alert(xhr.responseText);
        }
      };
      xhr.send();
    }

Como enviar uma solicitação autenticada

  1. No diretório em que você clonou o repositório web-docs-samples, mude para o diretório que contém a amostra de JavaScript:

    cd YOUR_WORKING_DIRECTORY/web-docs-samples/endpoints-frameworks
    
  2. Inicie o servidor da Web para exibir index.html na porta 8080. O exemplo a seguir usa o servidor simples do Python:

    python -m http.server 8080
    
  3. No navegador, digite localhost:8080.

    O aplicativo em JavaScript exibirá dois botões.

    Fazer login

  4. Clique em Fazer login. A página Fazer login com o Google é exibida.

  5. Depois de fazer login, clique no botão Enviar solicitação de amostra. Ao enviar uma solicitação pela primeira vez, pode ocorrer um atraso de cerca de 20 segundos enquanto o App Engine é iniciado. O Endpoints Frameworks intercepta as solicitações e usa o ID do cliente configurado no código de back-end para autenticar a solicitação. Se a autenticação for bem-sucedida:

    1. O Endpoints Frameworks transmitirá a solicitação para o back-end de amostra em execução no App Engine.

    2. No código de back-end, o método getUserEmail retorna o endereço de e-mail da conta de usuário usada ao fazer login.

    3. O cliente JavaScript exibe uma caixa de diálogo com o endereço de e-mail.

Visão geral do cliente JavaScript

O cliente JavaScript usa o Login do Google, que gerencia o fluxo do OAuth 2.0. Nesta seção, você verá uma breve visão geral do código do cliente JavaScript.

Configuração Auth

  1. Carregue a biblioteca da plataforma de APIs do Google para criar o objeto gapi:

      <script src="https://apis.google.com/js/platform.js?onload=loadAuthClient" async defer></script>
    </head>
  2. Depois que a biblioteca de plataformas de APIs do Google for carregada, carregue a biblioteca auth2:

    function loadAuthClient () {
      gapi.load('auth2', initGoogleAuth);
    }
  3. Inicialize o objeto GoogleAuth:

    function initGoogleAuth (clientId = 'YOUR_CLIENT_ID') {
      gapi.auth2.init({
        client_id: clientId,
        scope: 'https://www.googleapis.com/auth/userinfo.email'
      }).then(() => {
        document.getElementById('sign-in-btn').disabled = false;
      }).catch(err => {
        console.log(err);
      });
    }

Ao inicializar o objeto GoogleAuth, configure-o com o ID do cliente OAuth 2.0 e as outras opções que queira especificar. Normalmente, o escopo de acesso é especificado. Os escopos permitem que seu aplicativo solicite acesso apenas aos recursos necessários, além de permitir que os usuários controlem o nível de acesso que concedem ao seu aplicativo. Antes de começar a implantar a autorização do OAuth 2.0, recomenda-se identificar quais escopos o aplicativo precisa de permissão para acessar. Este exemplo solicita acesso ao escopo https://www.googleapis.com/auth/userinfo.email, que concede acesso para visualizar o endereço de e-mail do usuário.

Login

Depois de inicializar o objeto GoogleAuth, é possível solicitar que o usuário faça login chamando a função signIn do objeto GoogleAuth:

function signIn () {
  gapi.auth2.getAuthInstance().signIn().then(() => {
    document.getElementById('sign-in-btn').hidden = true;
    document.getElementById('sign-out-btn').hidden = false;
    document.getElementById('send-request-btn').disabled = false;
  }).catch(err => {
    console.log(err);
  });
}

Fazer uma solicitação com o token de código

Quando o usuário terminar de fazer login, envie uma solicitação com um cabeçalho de autorização com o token de ID do usuário:

function sendSampleRequest (projectId = 'YOUR_PROJECT_ID') {
  var user = gapi.auth2.getAuthInstance().currentUser.get();
  var idToken = user.getAuthResponse().id_token;
  var endpoint = `https://${projectId}.appspot.com/_ah/api/echo/v1/email`;
  var xhr = new XMLHttpRequest();
  xhr.open('GET', endpoint + '?access_token=' + encodeURIComponent(idToken));
  xhr.onreadystatechange = function () {
    if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
      window.alert(xhr.responseText);
    }
  };
  xhr.send();
}

A seguir