Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Node.js
Code

Autenticando Aplicações Node.js com Passport

by
Difficulty:IntermediateLength:LongLanguages:

Portuguese (Português) translation by Erick Patrick (you can also view the original English article)

Implementar estratégias robustas de autenticação para qualquer aplicação pode ser uma tarefa bem assustadora e as apliocações Node.js não são exceções.

Nesse tutorial, desenvolveremos uma aplicação em Node.js, a partir do zero, e usaremos um middleware relativamente novo, porém, bastante popular, o Passport, para cuidar da autenticação de nossa aplicação

A documentação do Passport a descreve como "um middleware simples e discreto para node". E realmente é.

Ao posicionar-se como um middleware, o Passaport faz um excelente trabalho ao separar os outros pontos de uma aplicação web das necessidades de autenticação. Isso permite que o Passaport seja facilmente configurada em qualquer aplicação baseada em Express, da mesma forma que configuramos qualquer outro middleware como o logging, body-parsing, cookie-parsing, manipuladores de sessão, etc.

Esse tutorial assume que tenha um entendimento básico de Node.js e da framework Express e tentará manter o foco na parte de autenticação, embora criaremos uma aplicação baseada em Express, a partir do zero, indo da criação das rotas à adição da camada de autenticação a alguma dessas rotas.

Estratégias de Autenticação

O Passport provê mais de 140 mecanismos de autenticação para escolhermos. Você pode autenticar em relação a uma instância remota/local de base de dados ou usar algum provedor OAuth para autenticar com redes sociais, como Facebook, Twitter, Google, etc, ou ainda pode escolher algum método de uma lista extensiva de provedores que dão suporte a autenticação com Passport e provê um módulo para usarmos.

Mas, não se preocupe: Você não precisa adicionar qualquer estratégia/mecanismo de autenticação que sua aplicação não precise. Todas essas estratégias são independentes umas das outras e empacotadas como módulos separados do node, e não estão inclusas por padrão, ao instalar o Passaport: npm install passport

Nesse tutorial, usaremos uma Estratégia de Autenticação Local do Passport para autenticar os usuários em relação a uma instância configurada e local do Mongo DB, guardando os detalhes do usuário nessa base de dados. Para usar essa estratégia, precisamos instalar o módulo passport-local: npm install passport-local

Mas, espere: Antes de abrir sua linha de comando e começar a executar esses comandos, comecemos criando a aplicação Express e adicionemos algumas rotas (como as login, registration e home) e tentemos adicionar nosso middleware de autenticação. Note que usaremos o Express 4 nesse tutorial, mas, com alguns ajustes, o Passport funcionará do mesmo jeito com o Express 3.

Preparando a Aplicação

Se você não o tiver feito ainda, instale o Express & express-generator para gerar o esqueleto de uma aplicação, bastando executar express passport-mongo na sua linha de comando. A estrutura da aplicação gerada deve parecer com isso:

Initial Application Structure

Removamos parte da funcionalidade padrão a qual não usaremos - vá em frente e apague o arquivo users.js bem como as referências a ele do arquivo app.js.

Adicionando Dependências ao Projeto

Abra o arquivo package.json e adicione os módulos passport e passport-local como dependência.

Como guardaremos os detalhes dos usuários no MongoDB, usaremos o Mongoose como nossa ferramenta modeladora de objetos de dados. Outra maneira de instalar e salvar essas dependências no package.json é digitando:

Seu package.json deve parecer com isso:

Added Mongoose Dependencies

Agora, instale as dependências e rode a aplicação padrão, executando os comandos npm install && npm start. Ele começará o download das dependências e iniciará nosso servidor node. Você pode verificar nosso app Express no endereço http://localhost:3000/, embora não tenha muito o que se ver por lá.

Logo mudaremos isso, criando um app Express completa, com página de registro de novos usuários; página de login dos usuários; e autenticação dos usuários registrados usando Passport.

Criando o Modelo com Mongoose

Já que salvaremos os dados do usuário no Mongo, criemos um modelo User usando Mongoose e o salvemos como models/user.js em nosso app.

Basicamente, criamos o model usando Mongoose, o qual poderemos realizar operações CRUD na base de dados usada.

Configurando o Mongo

Se não tiver o Mongo instalado localmente, recomendo que use serviços de bases de dado na nuvem, como o Modulus ou o MongoLab. Criar uma instância do MongoDB usando algum desses serviços, além de gratuito, só leva alguns cliques.

Depois de criar uma base de dados nesses serviços, ele fornecerá uma URI parecida com isso mongodb://<dbuser>:<dbpassword>@novus.modulusmongo.net:27017/<dbName>, que poderá ser usada para a realização das operações CRUD. É uma boa ideia manter a configuração da base de dados em um arquivo separado que pode ser utilizado quando necessário. Dessa forma, criaremos um módulo node, db.js, dessa forma:

Se você, assim como eu, usa uma instância local do Mongo, é hora de iniciar a daemon mongod e o db.js deverá ficar assim, para esse tipo de situação:

Agora, usaremos essa configuração no app.js e conectaremos a ela usando as APIs do Mongoose

Configurando o Passport

O Passport apenas provê o mecanismo de manipulação da autenticação, deixando a parte de manipulação de sessão para nós mesmos. Dessa forma, usaremos o express-session para lidar com essa parte. Abra o arquivo app.js e cole o código abaixo antes de configurarmos as rotas:

Isso é necessário se quisermos que nossas sessões sejam persistentes por natureza. Antes de executar o app, precisamos instalar o módulo express-session e adicioná-lo na lista de dependências do package.json. Faça isso, executando o comando a seguir na linha de comando: npm install --save express-session

Serializando e Deserializando Instâncias de Usuário

O Passport também precisa serializar e deserializar instâncias de objetos do armazenador de sessões, para dar suporte às sessões do login, assim, toda requisição subsequente não precisará lidar com credenciais do usuário. Ele provê dois métodos, serializeUser e deserializeUser para esse propósito:

Usando as Estratégias do Passport

Definiremos estratégias do Passport para manipular o login e o cadastro de usuários. Cada uma delas será uma instância da Estratégia Local de Autenticação do Passport e será criada usando a função passport.use(). Nós usaremos o módulo connect-flash para nos ajudar a manipular os erros, usando mensagens flash que podem ser usadas para mostrar os erros para o usuário.

Estratégia de Login

A estratégia de login parecerá com isso:

O primeiro parâmetro de passport.use() é o nome da estratégia que utilizaremos para identificar a estratégia em questão, quando precisarmos utiliza-la futuramente. O segundo parâmetro é o tipo da estratégia que queremos criar. Aqui, usamos username-password (usuário-senha) ou a LocalStrategy. É preciso notar que, por padrão, a LocalStrategy espera encontrar as credenciais do usuário nos parâmetros username & password, mas permite que usemos qualquer outro parâmetro nomeado também. A variável de configuração passReqToCallback permite-nos acessar o objeto request na callback, possibilitando, assim, usarmos qualquer parâmetro associado à requisição

Depois, usamos a API do Mongoose para encontrar o usuário em nossa coleção de Usuários, para verificar se é um usuário válido ou não. O último parâmetro em nossa callback, done, denota um método útil que nos permite sinalizar o sucesso ou falha do módulo Passport. Para especificar uma falha, ou o primeiro parâmetro contém um erro ou o segundo parâmetro deve ser algum valor que, se convertido para booleano, equivalha a false. Para denotar sucesso, o primeiro parâmetro deve ser null e o segundo parâmetro, se convertido para booleano, deve equivaler a true, que, nesse caso, estará disponível no objeto request.

Como senhas são, inerentemente, fracas, nós sempre devemos criptografá-las antes de salvá-las na base de dados. Por isso, usamos o módulo bcrypt-nodejs para auxiliar na criptografia e descriptografia das senhas.

Se você acha que só ver trechos de código dificultas as coisas, preferindo ver o código completo e a aplicação em ação, sinta-se a vontade para navegar pelo código.

Estratégia de Registro

Agora, definiremos a próxima estratégia, a qual manipulará a inscrição de novos usuários e criará um novo registro em nossa base de dados Mongo DB:

Nós usamos, novamente, a API do Mongoose para verificar se já existe usuário com o nome de usuário fornecido. Se não existir, criaremos o usuário e salvamos as informações no MongoDB. Caso contrário retornaremos o erro usando a callback done e mensagens flash. Note que usamos o módulo bcrypt-nodejs para a criação do hash da senha, antes de savá-la:

Criando as Rotas

Se verificássemos a estrutura geral de nossa aplicação, ela estaria assim:

Birds Eye View of Our Application

Agora, definiremos as rotas da aplicação no módulo a seguir, o qual usa uma instância do Passport criada no arquivo app.js. Salve esse módulo em routes/index.js

A parte mais importante do trecho acima é o uso de passport.authenticate() para delegar a autenticação das estratégias de login e registro quando uma requisição HTTP POST for feita para as rotas /login e /signup, respectivamente. Note que não é obrigatório nomear as estratégias no caminho das rotas e elas podem ser nomeadas de qualquer outra forma.

Criando as Visões em Jade

Agora, criaremos as duas visões a seguir, para nossa aplicação:

  1. layout.jade contendo o layout básico & estilos CSS
  2. index.jade contendo a página de login com seu formulário e a opção de criar uma nova conta

Graças ao Bootstrap, nossa página de Login está assim:

Login Page for Our Passport App

Precisamos de duas outras visões para os detalhes do registro e para a página inicial da aplicação:

  1. register.jade contendo o formulário de registro
  2. home.jade com uma saudação e mostrando os detalhes do usuário

Se não estiver familiarizado com Jade, veja a documentação aqui.

Implementando a Funcionalidade de Saída

O Passport, sendo um middleware, pode adicionar certas propriedades e métodos nos objetos de requisição e resposta. Lançando mão dessa possibilidade, temos o método request.logout() que invalida a sessão do usuário em nossas propriedades.

Protegendo as Rotas

O Passport também dá a possibilidade de restringir acesso a certas rotas que não sejam permitidas para usuários anônimos. Isso significa que, se algum usuário tentar acessar http://localhost:3000/home sem estar autenticado na aplicação, ele será redirecionado para página inicial.

Conclusão

O Passport não é a única maneira que temos disponivel para criar estratégias de autenticação em aplicações Node.js. Exitem alternativas como a EveryAuth, mas a modularidade, flexibilidade, suporte da comunidade e o fato de ser apenas um middleware, faz do Passport a melhor escolha.

Para uma comparação detalhada entre os dois, eis um postinteressante & informativo, na perspectiva do próprio criador do Passport.

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.