Autenticação de aplicativos Node.js com o Passport

Implementar estratégias de autenticação robustas para qualquer aplicativo pode ser uma tarefa assustadora e os aplicativos Node.js não são exceção a isso.

Neste tutorial, desenvolveremos um aplicativo Node.js do zero e usaremos um middleware de autenticação relativamente novo, mas muito popular – o Passport para cuidar de nossas preocupações de autenticação.

A documentação do Passport o descreve como um “middleware de autenticação simples e discreto para Node” e com razão.

Ao fornecer a si mesmo como um middleware, o Passport faz um excelente trabalho ao separar as outras preocupações de um aplicativo da Web de suas necessidades de autenticação. Ele permite que o Passport seja facilmente configurado em qualquer aplicativo da Web baseado em Express, assim como configuramos outro middleware Express, como log, análise de corpo, análise de cookie, manipulação de sessão etc.

Este tutorial pressupõe uma compreensão básica do Node.js e da estrutura Express e tenta manter o foco na autenticação, embora criemos um aplicativo Express de exemplo do zero e progredimos adicionando rotas a ele e autenticando algumas dessas rotas.

Se você precisar de ajuda com qualquer coisa, desde depuração até novos recursos, tente trabalhar com alguns dos desenvolvedores JavaScript experientes no Envato Studio.

Desenvolvedores JavaScript no Envato StudioDesenvolvedores JavaScript no Envato StudioDesenvolvedores JavaScript no Envato Studio
Desenvolvedores JavaScript no Envato Studio

Estratégias de autenticação

O Passport nos fornece mais de 140 mecanismos de autenticação para escolher. Você pode autenticar em uma instância de banco de dados local/remota ou usar o logon único usando provedores OAuth para Facebook, Twitter, Google etc. com o Passport e forneça um módulo de nó para isso.

Mas não se preocupe: você não precisa incluir nenhuma estratégia/mecanismo que seu aplicativo não precise. Todas essas estratégias são independentes umas das outras e empacotadas como módulos de nó separados que não são incluídos por padrão quando você instala o middleware do Passport: npm install passport

Neste tutorial, usaremos a Estratégia de Autenticação Local do Passport e autenticaremos os usuários em uma instância do Mongo DB configurada localmente, armazenando os detalhes do usuário no banco de dados. Para usar a Estratégia de Autenticação Local, precisamos instalar o módulo local do passaporte: npm install passport-local

Mas espere: antes de iniciar seu terminal e começar a executar esses comandos, vamos começar construindo um aplicativo Express do zero e adicionar algumas rotas a ele (para login, registro e home) e depois tentar adicionar nosso middleware de autenticação a ele. Observe que usaremos o Express 4 para os propósitos deste tutorial, mas com algumas pequenas diferenças, o Passport também funciona bem com o Express 3.

Configurando o aplicativo

Se você ainda não o fez, vá em frente e instale o Express & express-generator para gerar um aplicativo clichê simplesmente executando express passport-mongo no terminal. A estrutura do aplicativo gerado deve ficar assim:

Estrutura inicial do aplicativoEstrutura inicial do aplicativoEstrutura inicial do aplicativo

Vamos remover algumas das funcionalidades padrão que não usaremos – vá em frente e exclua o users.js rota e remova suas referências do app.js Arquivo.

Adicionando dependências do projeto

Abra package.json e adicione as dependências para passport e passport-local módulo.

Como salvaremos os detalhes do usuário no MongoDB, usaremos o Mongoose como nossa ferramenta de modelagem de dados de objetos. Outra maneira de instalar e salvar a dependência para package.json é digitando:

package.json deve ficar assim:

Adicionadas Dependências de MangustoAdicionadas Dependências de MangustoAdicionadas Dependências de Mangusto

Agora, instale todas as dependências e execute o aplicativo clichê executando npm install && npm start. Ele agora baixará e instalará todas as dependências e iniciará o servidor do nó. Você pode verificar o aplicativo Express básico em http://localhost:3000/, mas não há muito o que ver.

Muito em breve, vamos mudar isso criando um aplicativo expresso completo que pede para mostrar uma página de registro para um novo usuário, o login de um usuário registrado e autenticar o usuário registrado usando o Passport.

Criando Modelo Mangusto

Como estaremos salvando os detalhes do usuário no Mongo, vamos criar um modelo de usuário no Mongoose e salvá-lo em models/user.js em nosso aplicativo.

Basicamente, estamos criando um modelo Mongoose usando o qual podemos realizar operações CRUD no banco de dados subjacente.

Configurando o Mongo

Se você não tiver o Mongo instalado localmente, recomendamos que você use serviços de banco de dados em nuvem, como Modulus ou MongoLab. Criar uma instância funcional do MongoDB usando isso não é apenas gratuito, mas é apenas uma questão de alguns cliques.

Depois de criar um banco de dados em um desses serviços, ele fornecerá um URI de banco de dados comomongodb://:@novus.modulusmongo.net:27017/ que pode ser usado para executar operações CRUD no banco de dados. É uma boa ideia manter a configuração do banco de dados em um arquivo separado que pode ser acessado quando necessário. Como tal, criamos um módulo de nó db.js que se parece com:

Se você é como eu, está usando uma instância local do Mongo, então é hora de iniciar o mongod demônio e o db.js deve parecer

Agora usamos essa configuração em app.js e conecte-se a ele usando APIs do Mongoose:

Configurando o Passport

O Passport apenas fornece o mecanismo para lidar com a autenticação, deixando o ônus de implementar o tratamento de sessão e para isso usaremos a sessão expressa. Abra app.js e cole o código abaixo antes de configurar as rotas:

Isso é necessário, pois queremos que nossas sessões de usuário sejam persistentes por natureza. Antes de executar o aplicativo, precisamos instalar a sessão expressa e adicioná-la à nossa lista de dependências em package.json. Para fazer esse tipo npm install --save express-session

Serializando e desserializando instâncias de usuário

O Passport também precisa serializar e desserializar a instância do usuário de um armazenamento de sessão para oferecer suporte a sessões de login, para que cada solicitação subsequente não contenha as credenciais do usuário. Ele fornece dois métodos serializeUser e deserializeUser para o efeito:

Usando estratégias de passaporte

Vamos agora definir as estratégias do Passport para lidar com Conecte-se e inscrever-se. Cada um deles seria uma instância do Estratégia de autenticação local de Passaporte e seria criado usando o passport.use() função. Usamos o connect-flash para nos ajudar no tratamento de erros, fornecendo mensagens em flash que podem ser exibidas ao usuário em caso de erro.

Estratégia de login

A estratégia de login é assim:

O primeiro parâmetro a passport.use() é o nome da estratégia que será usada para identificar esta estratégia quando aplicada mais tarde. O segundo parâmetro é o modelo de estratégia que você deseja criar, aqui usamos o nome de usuário-senha ou o LocalStrategy. Deve-se notar que, por padrão, o LocalStrategy espera encontrar as credenciais do usuário em username & password parâmetros, mas também nos permite usar quaisquer outros parâmetros nomeados. o passReqToCallback variável de configuração nos permite acessar o request objeto no retorno de chamada, permitindo-nos usar qualquer parâmetro associado à solicitação.

Em seguida, usamos a API do Mongoose para encontrar o usuário em nossa coleção subjacente de usuários para verificar se o usuário é um usuário válido ou não. O último parâmetro em nosso retorno de chamada: done denota um método útil com o qual podemos sinalizar sucesso ou falha no módulo Passport. Para especificar a falha, o primeiro parâmetro deve conter o erro ou o segundo parâmetro deve avaliar para false. Para significar sucesso, o primeiro parâmetro deve ser null e o segundo parâmetro deve avaliar para um truthy valor, caso em que será disponibilizado no request objeto

Como as senhas são inerentemente fracas por natureza, devemos sempre criptografá-las antes de salvá-las no banco de dados. Para isso, usamos bcrypt-nodejs para nos ajudar com criptografia e descriptografia de senhas.

Se você está se sentindo desconfortável com os trechos de código e prefere ver o código completo em ação, sinta-se à vontade para navegar pelo código aqui.

Estratégia de registro

Agora, definimos a próxima estratégia que tratará do registro de um novo usuário e criará sua entrada em nosso Mongo DB subjacente:

Aqui, novamente usamos a API do Mongoose para descobrir se algum usuário com o nome de usuário fornecido já existe ou não. Caso contrário, crie um novo usuário e salve as informações do usuário no Mongo. Caso contrário, retorne o erro usando o done mensagens de retorno de chamada e flash. Observe que usamos bcrypt-nodejs para criar o hash da senha antes de salvá-la:

Criando Rotas

Se tivéssemos uma visão panorâmica do nosso aplicativo, ficaria assim:

Visão geral do nosso aplicativoVisão geral do nosso aplicativoVisão geral do nosso aplicativo

Agora definimos nossas rotas para o aplicativo no módulo a seguir que recebe a instância do Passport criada em app.js acima de. Salve este módulo em routes/index.js

A parte mais importante do trecho de código acima é o uso de passport.authenticate() delegar a autenticação para login e signup estratégias quando um HTTP POST é feito para /login e /signup rotas respectivamente. Observe que não é obrigatório nomear as estratégias no caminho da rota e pode ser qualquer nome.

Criando Vistas de Jade

Em seguida, criamos as duas visualizações a seguir para nosso aplicativo:

  1. layout.jade contém as informações básicas de layout e estilo
  2. index.jade contém a página de login contendo o formulário de login e dando a opção de criar uma nova conta

Graças ao Bootstrap, nossa página de login agora se parece com

Página de login para nosso aplicativo de passaportePágina de login para nosso aplicativo de passaportePágina de login para nosso aplicativo de passaporte

Precisamos de mais duas visualizações para detalhes de registro e para a página inicial do aplicativo:

  1. register.jade contém o formulário de inscrição
  2. home.jade diz olá e mostra os detalhes do usuário conectado

Se você não estiver familiarizado com o Jade, confira a documentação.

Implementando a funcionalidade de logout

O Passport, sendo um middleware, tem permissão para adicionar certas propriedades e métodos em objetos de solicitação e resposta e faz uso adequado dele adicionando um muito útil request.logout() método que invalida a sessão do usuário além de outras propriedades.

Protegendo Rotas

O Passport também oferece a capacidade de proteger o acesso a uma rota considerada imprópria para um usuário anônimo. Isso significa que se algum usuário tentar acessar http://localhost:3000/home sem se autenticar na aplicação, ele será redirecionado para a página inicial fazendo

Conclusão

O Passport não é o único jogador nessa área quando se trata de autenticar aplicativos Node.js e existem alternativas como EveryAuth, mas a modularidade, flexibilidade, suporte da comunidade e o fato de ser apenas um middleware tornam o Passport definitivamente uma escolha muito melhor.

Para uma comparação detalhada entre os dois, aqui está uma perspectiva interessante e informativa do próprio desenvolvedor do Passport.

Se você quiser ver o que mais você pode fazer com o Node.js, confira a variedade de itens do Node.js no Envato Market, desde um formulário de contato AJAX responsivo até um encurtador de URL ou até mesmo um gerador de CRUD de banco de dados.

Deixe um comentário

O seu endereço de e-mail não será publicado.