Exercício – Gerenciar o ciclo de vida da solicitação

Concluído

A Tailwind Traders precisa de seu aplicativo para ter alguma segurança básica. O aplicativo Expresso deve diferenciar entre clientes registrados que têm acesso e outros usuários que não devem ter acesso. Outros recursos, como o gerenciamento de funções, podem ser adicionados posteriormente.

Adicionar autorização básica a uma estrutura Express

A maioria dos aplicativos tem partes que podem ser acessadas por qualquer pessoa. No entanto, algumas partes precisam ser protegidas. Há diferentes maneiras de proteger um aplicativo. Neste exercício, você implementará um sistema de proteção simples para entender como o mecanismo de middleware funciona na estrutura Express.

Criar um servidor Web

Neste exercício, continue a usar o contêiner de desenvolvimento. Um projeto de amostra que tem arquivos de produto e código de aplicativo inicial é fornecido para você. Você preencherá as partes ausentes do projeto para concluir as atualizações do aplicativo para o cliente.

  1. Abra a pasta node-essentials/nodejs-http/exercise-express-middleware em um terminal clicando com o botão direito do mouse no nome da pasta e selecionando Abrir no terminal integrado.

    Esta pasta tem três arquivos: app.js, client.js e package.json.

  2. O arquivo package.json contém uma dependência chamada express. Execute o seguinte comando para instalar a dependência:

    npm install
    

    npm lê a seção dependencies no arquivo package.json e instala os pacotes necessários.

  3. Em um editor de código, abra o arquivo app.js e inspecione o conteúdo:

    const express = require("express");
    const app = express();
    const port = 3000;
    
    app.get("/", (req, res) => res.send("Hello World!"));
    
    app.get("/users", (req, res) => {
      res.json([
        {
          id: 1,
          name: "User Userson",
        },
      ]);
    });
    
    app.get("/products", (req, res) => {
      res.json([
        {
          id: 1,
          name: "The Bluest Eye",
        },
      ]);
    });
    
    app.listen(port, () => console.log(`Example app listening on port ${port}!`));
    

    O código contém um aplicativo Express funcional com três rotas: barra /, /users e /products.

Criar um aplicativo cliente

Em um editor de código, abra o arquivo de aplicativo client.js e inspecione o conteúdo:

const http = require('http');

const options = {
  port: 3000,
  hostname: 'localhost',
  path: '/users',
  headers: {}
};

const req = http.get(options, (res) => {
  console.log(`Connected - Status Code ${res.statusCode}`);

  res.on('data', (chunk) => {
    console.log("Chunk data: ", chunk.toString());
  });

  res.on('end', () => {
    console.log('No more data');
  });

  res.on('close', () => {
    console.log('Connection closed');
  });
});

req.on('error', (error) => {
  console.error('An error occurred: ', error);
});

req.end();

Esse código é um cliente do HTTP simples que se conecta ao aplicativo Expresso. Não é um navegador da Web. Ele não renderiza o HTML. Ele se conecta apenas ao servidor e faz a leitura dos dados retornados. É um bom exemplo de como usar o módulo HTTP do Node.js.

O código do aplicativo cliente se conecta ao endereço http://localhost:3000/users da rota /users. O cliente escuta três eventos: data, end e close. Ao emitir um evento, todas as funções anexadas a esse evento específico são chamadas de forma síncrona. Isso garante o sequenciamento adequado de eventos e ajuda a evitar condições de corrida e erros lógicos. Quando apropriado, as funções de ouvinte podem alternar para um modo assíncrono de operação usando os métodos setImmediate() ou process.nextTick(). Isso não é abordado neste módulo.

Executar o programa Express

Agora você está pronto para experimentar o programa Express com um aplicativo cliente.

  1. No terminal, inicie o programa do servidor Express digitando este comando:

    node app.js
    

    Observação

    Verifique se você está executando o arquivo app.js localizado em /nodejs-http/exercise-express-middleware.

  2. Abra um segundo terminal e inicie o aplicativo cliente:

    node client.js
    

    No segundo terminal, você verá a seguinte saída do cliente:

    connected - statusCode: 200
    chunk [{"id":1,"name":"User Userson"}]
    No more data
    Closing connection
    

    O servidor Expresso responde com alguns dados do usuário, chunk [{"id":1,"name":"User Userson"}]. Todas as partes do aplicativo funcionam.

    O aplicativo cliente fecha depois que ele exibe a saída.

  3. No primeiro terminal (o servidor Express), pressione Ctrl + C para interromper o programa.

Proteger a rota

Para proteger essa rota, adicionaremos um código ao aplicativo Express.

  1. Em um editor de código, abra o arquivo /nodejs-http/exercise-express-middleware/app.js. Localize a instrução const app = express(). Após essa instrução, adicione o seguinte código:

    function isAuthorized(req, res, next) {
       const authHeader = req.headers.authorization;
    
       if (!authHeader || authHeader !== 'secretpassword') {
         return res.status(401).send('Unauthorized: Access Denied');
       }
    
       next();
     }
    
  2. Em seguida, localize a seguinte seção de código no mesmo arquivo:

    app.get("/users", (req, res) => {
      res.json([
        {
          id: 1,
          name: "User Userson",
        },
      ]);
    });
    
  3. Substitua esta seção pelo código a seguir para que o middleware isAuthorized seja o segundo argumento:

    app.get("/users", isAuthorized, (req, res) => {
      res.json([
        {
          id: 1,
          name: "User Userson",
        },
      ]);
    });
    

Executar o programa Express e invocar o middleware

Tente usar o aplicativo cliente novamente com o programa de servidor atualizado.

  1. No primeiro terminal, execute o seguinte comando para reiniciar o programa Express:

    node app.js
    
  2. No segundo terminal, reinicie o aplicativo cliente:

    node client.js
    

    No segundo terminal, você verá a seguinte saída:

    connected - statusCode: 401
    chunk Not permitted
    No more data
    Closing connection
    

    Dessa vez, o middleware isAuthorized() é invocado e procura um cabeçalho authorization que tem um valor específico. Como você não forneceu um valor específico como parte da solicitação, o código não respondeu com os dados específicos do usuário. Em vez disso, a resposta foi chunk Not permitted. Você adicionará uma autorização específica na próxima seção.

  3. No primeiro terminal, pressione CTRL + C para interromper o programa.

Adicionar um cabeçalho de autorização

Você precisa adicionar um cabeçalho authorization para um valor específico.

  1. Em um editor de código, abra o arquivo nodejs-http/exercise-express-middleware/client.js novamente. Localize a seguinte instrução:

    headers: {},
    
  2. Substitua essa instrução pelo seguinte código:

    headers: {
      authorization: 'secretpassword'
    },
    

Executar o programa Express com a autorização do cliente

Tente usar o cliente novamente com um cabeçalho authorization.

  1. No primeiro terminal, execute o seguinte comando para reiniciar o programa Express:

    node app.js
    
  2. No segundo terminal, use o seguinte comando para executar mais uma vez o cliente:

    node client.js
    

    No segundo terminal, agora você verá a seguinte saída:

    connected - statusCode: 200
    chunk [{"id":1,"name":"User Userson"}]
    No more data
    Closing connection
    

    Os dados do usuário foram retornados porque você passou um cabeçalho de authorization com um valor aceito.

  3. No primeiro terminal, pressione CTRL + C para interromper o programa.

Parabéns! Você aprendeu como usar middleware no Express para adicionar pré-processamento e autorização básica ao seu programa do Express.

Cuidado

Lembre-se de que uma autenticação/autorização destinada ao uso real precisa ser mais robusta do que este exemplo. Vale a pena pesquisar conceitos como OAuth, Tokens Web JSON, JWT e a biblioteca bcrypt para garantir que o aplicativo tenha proteção contra usuários não autorizados.

Limpar o contêiner de desenvolvimento

Depois de concluir o projeto, limpe o ambiente de desenvolvimento ou devolva-o ao estado padrão.

A exclusão do ambiente GitHub Codespaces garante que você possa maximizar a quantidade de horas gratuitas por núcleo que você tem direito na sua conta.

Importante

Para saber mais sobre os direitos da sua conta do GitHub, confira O GitHub Codespaces inclui mensalmente armazenamento e horas de núcleo.

  1. Entre no painel do GitHub Codespaces (https://github.com/codespaces).

  2. Localize seus Codespaces atualmente em execução, originados do repositório MicrosoftDocs/node-essentials do GitHub.

    Screenshot of all the running codespaces including their status and templates.

  3. Abra o menu de contexto do codespace e selecione Excluir.

    Screenshot of the context menu for a single codespace with the delete option highlighted.