Cursos / Informática para Internet / Plataformas de aplicações Web / Aula

arrow_back Aula 10 - PetTopStore - Admin - Parte 2

Rotas de autenticação

O arquivo app.js importa o routes/auth.js, que ainda não está criado. Ele terá as seguintes rotas com as seguintes responsabilidades:

  • GET /login_form (renderiza uma view EJS com o formulário de login)
  • POST /sign_in (realiza o login do usuário (se acertar email/senha com o que está no banco de dados) e redireciona para a página inicial)
  • GET /sign_out (desloga o usuário)

Crie o arquivo routes/auth.js com o seguinte conteúdo:

// importa a configuração do knex do knexfile.js
var knexConfig = require('../knexfile');
// importa o knex aplicando a configuração
var knex = require('knex')(knexConfig);
var bcrypt = require('bcrypt');
var express = require('express');
var router = express.Router();

// exibe o formulário de login
router.get('/login_form', async (req, res) => {
  // renderiza formulário EJS (view)
  res.render('auth/login_form', { error: req.query.error });
});

// tenta logar o employee e redirecionar para a raiz do sistema
router.post('/sign_in', async (req, res) => {
  // busca employee no banco com esse email
  const employee = await knex.table('employees').where({ email: req.body.email, is_admin: true }).first();
  if (!employee) {
    return res.redirect('/auth/login_form?error=1');
  }
  // compara a senha passada pelo formulário com a senha critografa no banco de dados
  if ( bcrypt.compareSync(req.body.password, employee.password) ) {
    // se senha é correta, guarda o ID do employee na sessão
    // permitindo que seja utilizado em outras rotas
    req.session.logged_as = employee.id;
    // redireciona usuário para a raiz do sistema
    return res.redirect('/');
  } else {
    // caso a senha seja incorreta limpa sessão do cookie-session
    req.session = null;

    // redireciona usuário para o formulário de login novamente, com um parâmetro de erro=1
    return res.redirect('/auth/login_form?error=1');
  }
});

// desloga o employee e redireciona para o form de login
router.get('/sign_out', async (req, res) => {
  req.session = null;
  return res.redirect('/auth/login_form');

});

module.exports = router;

Vamos analisar cada comando…

Na rota de /auth/login_form simplesmente um formulário HTML+EJS será exibido solicitando o e-mail e senha e com o action para '/auth/sign_in'. É repassado para a view o parâmetro error caso ele esteja presente na URL, o que indica que a tentativa de login falhou.

A rota /auth/sign_in recebe o email e password enviado pelo login_form e algumas ações foram são realizadas na tentativa de verificar se existe no banco de dado sum employee com esse email/password e com is_admin=true (verificar se o login é correto para um administrador).

O comando abaixo utiliza o knex para buscar o primeiro employee que casa com a restrição do email ser igual ao passado pelo formulário (req.body.email) e o campo is_admin=true. Não é verificado a senha ainda, somente o employee com o email informado é salvo na variável employee:

const employee = await knex.table('employees').where({ email: req.body.email, is_admin: true }).first();

Em seguida é verificado se employee não existe, ou seja, não existe employee com o email informado. Caso seja o caso, redireciona para o login_form com erro=1

if (!employee) {
    return res.redirect('/auth/login_form?error=1');
  }

Em seguida usamos o bcrypt para compara a senha do formulário (req.body.password) com a senha criptografada do employee obtido do banco de dados

if ( bcrypt.compareSync(req.body.password, employee.password) ) {

Caso seja correta, usamos é criada uma variável chamada logged_as na sessão com o ID do employee (usuário) logado com sucesso. Em seguida redireciona o usuário para a raiz do site:

req.session.logged_as = employee.id;

return res.redirect('/');

Essa variável em req.session.logged_as ficará disponível em outras rotas nas requisições subsequentes ao servidor.

Caso a senha não case com a que está criptografada no banco de dados, limpa a sessão e manda o usuário para o login_form com erro=1

req.session = null;
return res.redirect('/auth/login_form?error=1');

Na rota /auth/sign_out temos uma ação bem simples. Limpa a sessão com req.session = null e em seguida manda o usuário para o /auth/login_form. Isso significa "deslogar o usuário".

Pronto. Temos um mecanismo de login simples, porém seguro e eficiente, utilizando banco de dados e cookies criptografados.


Versão 5.3 - Todos os Direitos reservados