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

arrow_back Aula 10 - PetTopStore - Admin - Parte 2

Restringindo acesso ao sistema

Nossa autenticação está pronta, porém como você pode perceber é possível acessar a raiz do sistema http://localhost:3000/ mesmo sem está autenticado. Por enquanto essa página raiz é somente uma mensagem padrão do Express, mas no futuro teremos outras funcionalidades e não queremos que usuários não autorizados tenham acesso.

O comportamento desejado é que qualquer rota do sistema administrativo requer que o usuário esteja logado e caso ele não esteja deve ser redirecionado para /auth/login_form.

Para isso vamos criar um middleware personalizado chamado "requerAutenticacao" e aplicar nas rotas que não são /auth/alguma_coisa. As rotas em /auth não requerem autenticação, claro, já que o usuário está justamente tentando se autenticar ainda.

Para isso inicialmente crie uma pasta na raiz do projeto chamada "middlewares" e nela um arquivo middlewares/requireAuth.js com o seguinte conteúdo:

const knexConfig = require("../knexfile");

const knex = require('knex')(knexConfig);

module.exports = async (req, res, next) => {
  // verifica se a sessão está vazia (deslogado)
  if (! req.session || !req.session.logged_as) {
    return res.redirect('/auth/login_form');
  }
  // caso a sessão exista o usuário está logado.
  const idAdminLogado = req.session.logged_as;
  // buscar o administrador no banco de dados pelo id
  const employee = await knex.table('employees').where({ id: idAdminLogado }).first();
  // coloca o employee (administrador) logado no res.locals  para que ele fique disponível
  // para outros requests de forma completa (todos os dados do banco)
  res.locals.employee = employee;
  next();// continua a requisição que inclui esse middleware

}

Esse middleware inicialmente verifica se a sessão não existe, redireciona o usuário para o login_form. Depois, caso a sessão existe (administrador está logado), busca o employee com o ID que está na sessão (dentro de logged_as) e salva o objeto inteiro do employee (com name, email, etc) em res.locals.employee, o que permite que as rotas que usarem esse middleware tenham acesso a res.locals.employee com certeza que lá existe um employee que é administrador, está logado e com os dados disponíveis nesse objeto.

Vamos agora aplicar esse middleware na rota raiz do sistema.

No arquivo 'app.js' importe o middleware com:

const requireAuth = require('./middlewares/requireAuth');

e depois faça ele ser requisito da rota index, trocando a linha:

app.use('/', indexRouter);

por:

app.use('/', [requireAuth], indexRouter);

Isso fará que qualquer rota abaixo de "/" execute o requireAuth antes de ser executada.

É importante observar que no arquivo app.js o uso da rota "/auth" dev vir antes de "/" para que "/auth" não acabe também recebendo o middleware requireAuth, já que é uma rota mais específica. Então a ordem dos comandos de de uso de rotas no app.js fica assim:

// usando rotas de autenticação
app.use('/auth', authRouter);

// aplica o requireAuth middleware na raiz do site
app.use('/', [requireAuth], indexRouter);

Pronto. Dessa forma se o usuário não estiver logado e visitar a raiz do sistema ele será redirecionado automaticamente para "/auth/login_form" e se ele logar com sucesso poderá navegar para a raiz do sistema (e futuramente para outras funcionalidades)

Para conseguir exibir o usuário logado na página incial do sistema altere o routes/index.js com o seguinte conteúdo:

var express = require('express');

var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', {
    title: 'Pet Top Store',
    employee: res.locals.employee
  });

});

module.exports = router;

e também o views/index.ejs com o seguinte conteúdo:


<!DOCTYPE html>

<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
    <p>Logado como <%= employee.name %></p>
    <p>
      <a href="/auth/sign_out">Sair do sistema</a>
    </p>
  </body>

</html>

Veja que na rota "/" estamos repassando o res.locals.employee para a view. Repare também que a view index.ejs agora mostra o nome do employee e um link para "/auth/sign_out" (deslogar). Deve ficar como a imagem abaixo:

Formulário de login

Página inicial com restrição para usuários logados pelo middleware requireAuth


Versão 5.3 - Todos os Direitos reservados