Implementar a autenticação de aplicativos do zero pode ser uma grande dor de cabeça para os desenvolvedores. E, se não for implementado corretamente, o processo de autenticação pode levar a vulnerabilidades dentro de um sistema.

Neste artigo, implementaremos a autenticação em um aplicativo Node.js usando o Biblioteca do Passport e MongoDB .

O que é Passport.js?

Passport é uma autenticação modular popular middleware para aplicativos Node.js. Com ele, a autenticação pode ser facilmente integrada a qualquer aplicativo baseado em Node e Express. A biblioteca do Passport oferece mais de 500 mecanismos de autenticação, incluindo OAuth, JWT e autenticação simples baseada em nome de usuário e senha.

O uso do Passport também facilita a integração de mais de um tipo de autenticação no aplicativo. Vamos usar a estratégia local do mongoose neste artigo para implementar a autenticação.

Criando a estrutura de pastas do aplicativo Node

Primeiro, vamos criar pastas específicas para nossos arquivos, assim:

Aqui, a pasta de rotas contém o arquivo de todas as rotas. A pasta de visualizações contém os arquivos ejs que serão exibidos e a pasta de layout contém o código de layout ejs.

Além disso, temos um arquivo.env para armazenar as chaves, um arquivo index.js como um ponto de partida do aplicativo e um arquivo userDetails.js para o esquema Mongoose.

Construir um sistema de autenticação com Passport, passport-local-mongoose e MongoDB é extremamente simples, mas antes de prosseguir para a construção do aplicativo, nós precisará de um cluster MongoDB.

Você pode usar sua versão auto-hospedada do MongoDB ou pode usar o MongoDB Atlas. Em ambos os casos, crie primeiro um banco de dados MongoDB e armazene o URI SRV no arquivo.env.

Inicializando o Node e instalando os pacotes

Assim que terminarmos de criar um banco de dados, vamos inicializar a pasta com npm. Crie uma nova pasta e inicialize-a com npm init-y.

Em seguida, instale as dependências. Aqui está uma lista deles:

express: usaremos a estrutura Express para nosso aplicativo da web mongoose: o driver MongoDB para Node.js será usado para conectar com MongoDB ejs: nosso mecanismo de modelagem express-ejs-layouts: isso será usado para layouts dotenv: este pacote carrega as variáveis ​​de ambiente de um arquivo chamado.env para process.env connect-garantir-login: isso protege as páginas que exigem autenticação passport e passport-local-mongoose: para implementar autenticação express-sessão: para criar e gerenciar as sessões

Instale este pacote com:

npm i express mongoose ejs express-ejs-layouts dotenv conectar-garantir-login passaporte passaporte-local-mongoose express-sessão

Usaremos a dependência de dev do nodemon. Instale a dependência dev usando npm i-D nodemon e, em seguida, altere a seção de scripts do arquivo package.json com estas duas linhas:

“scripts”: {“start”:”node index.js”,”dev”:”nodemon index.js”}

Criando visualizações e layouts

Como usaremos ejs como o mecanismo de modelagem, estamos usando o pacote express-ejs-layouts para construir nosso layout padrão.

Embora a instalação deste plugin seja opcional, é útil ao trabalhar com um projeto grande. Primeiro, crie uma pasta chamada views no diretório raiz e, em seguida, crie uma pasta chamada layout dentro do diretório views.

Crie um arquivo chamado main.ejs dentro do diretório de layout. Estou usando o CSS do Bootstrap para estilizar as páginas da web neste aplicativo, então não precisarei escrever nenhum CSS. Não vou explicar os arquivos HTML aqui, pois eles são bastante diretos e podem ser entendidos facilmente. Aqui está o código para o arquivo main.ejs:

//anonymous”cross.jor”>//anonymous.net/npm/bootstrap @ 5.0.2/dist/js/bootstrap.bundle.min.js”Integrity=”sha384-MrcW6ZMFYlzcLA8Nl + NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP + JcXn/tWtIaxV>”crossortitin/tWtIaxVX>”crossMcriptin/tWtIaxV>”crossMcriptin/tWtIaxV>”crossMcript>”crossorXn/tWtIaxV> %-title%> %-body%>

Na seção de cabeçalho, importamos CSS e JavaScript Bootstrap usando CDN. O texto dentro da tag de título e o corpo serão alterados para cada visualização.

Por causa disso, estamos usando literais %-title%> e %-body%>. Passaremos o título de nosso arquivo de rotas e o corpo renderizará o corpo HTML.

Isso é tudo o que é necessário para adicionar ao arquivo main.ejs. Deixe-me mostrar o código para as outras três páginas.

1. index.ejs

Lorem ipsum dolor sit amet consectetur, adipisicing elit. Quod, quidem. Distinctio, natus, recusandae nostrum beatae provident aut quasi sequi eos nemo et quia dolor ipsum reprehenderit molestiae id facere sunt.

Veja como ele ficará quando o renderizarmos:

2. login.ejs

A única coisa a notar aqui é que estamos atingindo a rota de login usando o Método POST na ação do formulário. Fora isso, é um formulário HTML simples com rótulos. A página de login será semelhante a esta:

3. secret.ejs

Você acessou com sucesso a página secreta

A página secreta será parecida com esta:

Esta página contém um botão chamado logout que fará o logout dos usuários.
No entanto , nenhuma dessas páginas será renderizada ainda porque não configuramos nosso servidor. Vamos fazer isso agora.

Configurando o servidor

Vamos importar os pacotes no arquivo index.js.

//Módulos requeridos const express=require (‘express’); var expressLayouts=require (‘express-ejs-layouts’); const app=express ();//configurar mecanismo de visualização e layout app.use (expressLayouts); app.set (‘layout’,’./layout/main’); app.set (‘view engine’,’ejs’); app.use (express.urlencoded ({extended: false})); const PORT=process.env.PORT || 3000;//Configure o servidor expresso const server=app.listen (PORT, ()=> {console.log (`Ouvindo na porta $ {PORT}`);});

Aqui, importamos os pacotes express e express-ejs-layouts. Depois disso, inicializamos express e express-ejs-layouts com const app=express () e app.use (expressLayouts).

O app.set (‘layout’,’./layout/main’) está configurando o arquivo principal como o layout e app.set (‘view engine’,’ejs’) está configurando ejs como o mecanismo de modelagem. app.use (express.urlencoded ({extended: false})) funciona como o analisador de corpo. E, finalmente, estamos criando nosso servidor na porta 3000.

Agora, vamos criar uma nova pasta chamada rotas e, dentro da pasta, criar um novo arquivo chamado router.js.

const express=exigir (‘expresso’); roteador const=express.Router (); const connectEnsureLogin=require (‘conectar-garantir-login’); passaporte const=requer (‘passaporte’);//GET Routes router.get (‘/’, (req, res)=> {res.render (‘index’, {title:’Home’});}); router.get (‘/login’, (req, res)=> {res.render (‘login’, {título:’Login’});}); router.get (‘/secret’, connectEnsureLogin.ensureLoggedIn (), (req, res)=> res.render (‘secret’, {title:’Secret Page’})); router.get (‘/logout’, (req, res)=> {req.logout (); res.redirect (‘/’);});//POST Routes router.post (‘/login’, passport.authenticate (‘local’, {failureRedirect:’/login’, successRedirect:’/secret’,}), (req, res)=> {console.log (req.user);}); módulo.exportações=roteador;

Como você pode ver no código acima, temos três rotas GET e uma rota POST. Primeiro, adicionamos os pacotes necessários.

O middleware connectEnsureLogin.ensureLoggedIn () na rota secreta garante que o usuário seja proibido de entrar na página sem fazer login.

Dentro do Na rota POST, o middleware passport.authenticate autentica o usuário com a estratégia local e, se o usuário conseguir efetuar login, ele redirecionará para a rota secreta. Caso contrário, ele redirecionará para a rota de login.

Também estamos passando o título das páginas através da variável title. O req.logout () é um método de passaporte que desconecta o usuário. Finalmente, estamos exportando o roteador.

Configurando o esquema do usuário com MongoDB

Crie um novo arquivo no diretório raiz chamado userDetails.js.

const mongoose=require (‘mangusto’); const passportLocalMongoose=require (‘passport-local-mongoose’); require (‘dotenv’). config ();//Conectando Mongoose mongoose.connect (process.env.MONGODB_URI, {useNewUrlParser: true, useUnifiedTopology: true,});//Configurando o esquema const User=new mongoose.Schema ({username: String, password: String,});//Configurando o plugin do passaporte User.plugin (passportLocalMongoose); module.exports=mongoose.model (‘Usuário’, Usuário);

Exigimos o mongoose para se conectar ao MongoDB, e passport-local-mongoose torna extremamente fácil integrar a autenticação de nome de usuário e senha com o MongoDB.

Configuramos o pacote dotenv para usar as variáveis ​​de ambiente no próxima linha.

Então, estamos nos conectando ao banco de dados usando o mongoose. A variável de usuário está mantendo o esquema mongoose. O método User.plugin (passportLocalMongoose) gera e armazena o hash, salt e nome de usuário no banco de dados para cada usuário. Finalmente, exportamos o esquema.

Estamos quase terminando. Precisamos apenas configurar nosso arquivo index.js.

Inicializando o Passport no aplicativo Node

Vamos importar os módulos Passport e express-session, router.js e userDetails. arquivo js. Em seguida, configure a sessão usando o pacote express-session:

const passport=require (‘passport’); sessão const=requer (‘sessão expressa’); const UserDetails=require (‘./userDetails’); rotas const=requer (‘./rotas/roteador’); require (‘dotenv’). config ();//Configure a sessão app.use (session ({secret: process.env.SECRET, resave: false, saveUninitialized: true,}));

O segredo é armazenado no arquivo.env e assina o cookie de ID de sessão. Se o sinalizador resave for definido como verdadeiro, os dados da sessão serão armazenados à força. Não queremos isso porque o saveUninitialized salvará forçosamente sessões não inicializadas quando definido como verdadeiro. Você pode ler em detalhes sobre o pacote aqui .

Agora, configure Passport adicionando as seguintes linhas:

//Configure o Passport app.use (passport.initialize ()); app.use (passport.session ());

Estamos inicializando o Passport e o middleware de autenticação de sessão primeiro. Feito isso, temos que configurar a autenticação local.

passport.use (UserDetails.createStrategy ()); passport.serializeUser (UserDetails.serializeUser ()); passport.deserializeUser (UserDetails.deserializeUser ());

O código acima adiciona autenticação local ao nosso aplicativo Node. Primeiro, estamos definindo a estratégia local no modelo UserDetails chamando o método createStrategy.

Em seguida, o método serializeUser serializa a instância do usuário passada na autenticação, e a instância deserializeUser é chamada em cada solicitação subsequente para de-serialize o usuário.

Agora adicione este código em seu arquivo de índice e execute index.js apenas uma vez:

UserDetails.register ({username:’nemo’, active: false},’123′);

A linha acima registrará um usuário com nome de usuário nemo com senha 123. Se você verificar seu banco de dados MongoDB agora, verá o usuário.

O arquivo index.js final terá a seguinte aparência:

//Módulos requeridos const express=require (‘express’); var expressLayouts=require (‘express-ejs-layouts’); const app=express (); passaporte const=requer (‘passaporte’); sessão const=requer (‘sessão expressa’); const UserDetails=require (‘./userDetails’); rotas const=requer (‘./rotas/roteador’); require (‘dotenv’). config ();//Configurar mecanismo de visualização e layout app.use (expressLayouts); app.set (‘layout’,’./layout/main’); app.set (‘view engine’,’ejs’);//Configure a sessão app.use (session ({secret: process.env.SECRET, resave: false, saveUninitialized: true,})); app.use (express.urlencoded ({extended: false}));//Configure o Passport app.use (passport.initialize ()); app.use (passport.session ()); passport.use (UserDetails.createStrategy ()); passport.serializeUser (UserDetails.serializeUser ()); passport.deserializeUser (UserDetails.deserializeUser ()); app.use (rotas);//Configure o servidor expresso const server=app.listen (3000, ()=> {console.log (`Ouvindo na porta $ {server.address (). Port}`);}); UserDetails.register ({nome de usuário:’nemo’, ativo: falso},’123′);

Isso conclui a autenticação. Verifique o GIF abaixo para vê-lo em ação.

Conclusão

A autenticação é uma parte importante e integrante de muitos aplicativos da web. Este artigo abordou como integrar a autenticação a um aplicativo Node.js usando a biblioteca Passport e MongoDB.

Você também pode verificar o Passport Docs para mais estratégias de autenticação para implementar em seu aplicativo. Eu espero que você tenha gostado da leitura. O código completo pode ser encontrado neste repositório GitHub .