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

arrow_back Aula 11 - PetTopStore - Admin - Parte 3 (API)

API - routes/api/auth.js

Conteúdo:

var express = require('express');
var router = express.Router();

const knexConfig = require('../../knexfile');
const knex = require('knex')(knexConfig);

const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const segredoJWT = 'frase segredo para critografia do jwt';

// employee sign_in
router.post('/employee/sign_in', async(req, res) => {
  // busca employee no banco com esse email
  const employee = await knex.table('employees').where({ email: req.body.email }).first();

  // Caso o employee não exista ou sua senha criptografada seja diferente da armazenada no banco, retorna um erro:
  if (!employee || !bcrypt.compareSync(req.body.password, employee.password)) {
    return res.status(401).json({
      message: 'Funcionário não existe'
    });
  }

  // criação do conteúdo (payload) do token JWT com o employee encontrado e com senha correta
  const conteudoJWT = {
    employee: employee
  };

  // gera um token com o conteúdo (payload) e assinado com o segredoJWT. É atribuído uma expiração de 2 dias para o token.
  const token = jwt.sign(conteudoJWT, segredoJWT, { expiresIn: '2 days' });

  // o token é adicionado ao employee, que é retornado no JSON
  employee.token = token;
  return res.json({ employee });
});

// client sign_in
router.post('/client/sign_in', async(req, res) => {
  // busca client no banco com esse email
  const client = await knex.table('clients').where({ email: req.body.email }).first();

  // Caso o client não exista ou sua senha criptografada seja diferente da armazenada no banco, retorna um erro:
  if (!client || !bcrypt.compareSync(req.body.password, client.password)) {
    return res.status(401).json({
      message: 'Cliente não existe'
    });
  }

  // criação do conteúdo (payload) do token JWT com o employee encontrado e com senha correta
  const conteudoJWT = {
    client: client
  };

  // gera um token com o conteúdo (payload) e assinado com o segredoJWT. É atribuído uma expiração de 2 dias para o token.
  const token = jwt.sign(conteudoJWT, segredoJWT, { expiresIn: '2 days' });

  // o token é adicionado ao client, que é retornado no JSON
  client.token = token;
  return res.json({ client });
});

// client registration (from website)
router.post('/client/registration', async(req ,res) => {
  // busca client no banco com esse email
  const existingClient = await knex.table('clients').where({ email: req.body.email }).first();

  // Se o client já existe, retorna um erro pois não pode cadastrar dois com o mesmo e-mail
  if (existingClient) {
    return res.status(401).json({
      message: 'Cliente já existe com esse e-mail'
    });
  }

  // constroi o objeto com os dados do novo client(incluindo a senha critograda com o bcrypt)
  let newClientData = {
    name: req.body.name,
    email: req.body.email,
    password: bcrypt.hashSync(req.body.password, 10)
  };

  // insere o client no banco e recebe um array que deve conter só um elemento (o id do cliente inserido)
  let clientIDs = await knex.table('clients').insert(newClientData);

  // retorna uma mensagem de sucesso e o ID do client inserido no banco (primeiro elemento do array retornado pelo comando insert)
  return res.json({
    message: 'Cliente registrado com sucesso',
    clienteID: clientIDs[0]
  });
});

module.exports = router;

O arquivo auth.js é responsável pela autenticação da API, utilizando a estratégia de tokens JWT.

Existem 3 rotas nesse arquivo:

  • POST /employee/sign_in
  • POST /client/sign_in
  • POST /client/registration

Rotas /employee/sign_in e /client/sign_in e

Rota responsável por autenticar um employee (funcionário) ou um client (cliente) por email/senha e gerar um token. Os comentários no código da rota explicam o seu passo a passo.

  • Inicialmente é buscado o employee no banco pelo email ( Caso o employee/client não exista ou sua senha criptografada seja diferente da armazenada no banco, retorna um erro
  • É criado um token JWT com e dentro do payload os dados do employee
  • O token é inserido no employee e retornado como JSON

Node que a assinatura do token é setada para expirar em 2 dias com o comando:

const token = jwt.sign(conteudoJWT, segredoJWT, { expiresIn: '2 days' });

Isso cria um campo especial no token chamado "exp" com um valor que representa seu momento de expiração.

As rotas /employee/sign_in e /client/sign_in são muito parecidas, e única mudança é que uma autentica um funcionário e a outra um cliente da loja e o token JWT gerado muda um pouco pois retornam campos diferentes (employee para uma rota e client para a outra rota).

Essa diferença do JWT (client ou employee) permite que nos sistemas possa ser verificado se o JWT pertence a um cliente ou funcionário.

Rota /client/registration

Essa rota registra um novo cliente no banco de dados. Ela tem os detalhe o que acontece a cada comando comentado no seu código.

É uma rota simples que verifica se um cliente a ser registrado já existe no banco, caso contrário o registra com a senha informada criptografada com o bcrypt.

Tanto os funcionários logados no PDV poderão usar essa rota para cadastrar clientes na loja física, quanto os próprios clientes poderão usar a loja virtual para se cadastrar através dessa rota na API.


Versão 5.3 - Todos os Direitos reservados