Enviando dados de um lugar para outro? Para sua própria tranquilidade e proteção de seus usuários, você deve protegê-lo com o JWT.

Ao criar um aplicativo, é vital proteger dados confidenciais contra acesso não autorizado. Muitos aplicativos modernos da web, móveis e em nuvem usam APIs REST como o principal meio de comunicação. Como resultado, é crucial projetar e desenvolver APIs de back-end com segurança em primeiro lugar.

Uma abordagem eficaz para proteger uma API REST envolve JSON Web Tokens (JWTs). Esses tokens oferecem um mecanismo robusto para autenticação e autorização do usuário, ajudando a proteger os recursos protegidos contra o acesso de agentes mal-intencionados.

O que são tokens da Web JSON?

Token da Web JSON (JWT) é um padrão de segurança amplamente utilizado. Ele fornece um método conciso e independente de transmissão segura de dados entre um aplicativo cliente e um sistema de back-end.

Uma API REST pode usar JWTs para identificar e autenticar usuários com segurança quando eles fazem solicitações HTTP para acessar recursos protegidos.

instagram viewer

Um JSON Web Token consiste em três partes distintas: o cabeçalho, a carga útil e a assinatura. Ele codifica cada parte e as concatena usando um ponto (".").

O cabeçalho descreve o algoritmo criptográfico usado para assinar o token, enquanto a carga útil contém dados sobre o usuário e quaisquer metadados adicionais.

Por fim, a assinatura, calculada usando o cabeçalho, a carga útil e a chave secreta, garante a integridade e a autenticidade do token.

Com o básico dos JWTs resolvidos, vamos criar uma API REST Node.js e implementar JWTs.

Configurar um aplicativo Express.js e um banco de dados MongoDB

Você descobrirá aqui como criar uma autenticação simples API REST que lida com a funcionalidade de registro e login. Depois que o processo de login autenticar um usuário, ele poderá fazer solicitações HTTP para uma rota de API protegida.

Você pode encontrar o código do projeto neste Repositório GitHub.

Para começar, criar um servidor web Expresse instale estes pacotes:

npm install cors dotenv bycrpt mongoose cookie-parser crypto jsonwebtoken mongodb

Próximo, criar um banco de dados MongoDB ou configurar um cluster MongoDB na nuvem. Em seguida, copie a string de conexão do banco de dados, crie um .env arquivo no diretório raiz e cole na string de conexão:

CONNECTION_STRING="string de conexão"

Configurar a conexão do banco de dados

Crie um novo utils/db.js arquivo no diretório raiz da pasta do seu projeto. Nesse arquivo, adicione o seguinte código para estabelecer a conexão com o banco de dados usando o Mongoose.

const mangusto = exigir('mangusto');

const conectarDB = assíncrono () => {
tentar {
aguardam mongoose.connect (process.env. CONNECTION_STRING);
console.registro("Conectado ao MongoDB!");
} pegar (erro) {
console.erro("Erro ao conectar-se ao MongoDB:", erro);
}
};

módulo.exports = connectDB;

Definir o modelo de dados

Defina um esquema simples de dados do usuário usando o Mongoose. No diretório raiz, crie um novo modelo/usuário.model.js arquivo e adicione o seguinte código.

const mangusto = exigir('mangusto');

const userSchema = novo mangusto. Esquema({
nome de usuário: Corda,
senha: {
tipo: Corda,
obrigatório: verdadeiro,
exclusivo: verdadeiro,
},
});

const Usuário = mangusto.model("Do utilizador", userSchema);
módulo.exports = Usuário;

Defina os controladores para as rotas de API

As funções do controlador gerenciarão o registro e o login; eles são uma parte substancial deste programa de amostra. No diretório raiz, crie um controllers/userControllers.js arquivo e adicione o seguinte código:

  1. Defina o controlador de registro do usuário.
    const Usuário = exigir('../models/user.model');
    const bcrypt = exigir('bcrypt');
    const { gerarToken } = exigir('../middleware/auth');

    exports.registerUser = assíncrono (req, res) => {
    const { nome de usuário, senha } = req.body;

    tentar {
    const hash = aguardam bcrypt.hash (senha, 10);
    aguardam User.create({ nome de usuário, senha: cerquilha });
    res.status(201).enviar({ mensagem: 'Usuário cadastrado com sucesso' });
    } pegar (erro) {
    console.log (erro);
    res.status(500).enviar({ mensagem: 'Um erro ocorreu!! ' });
    }
    };

    Este trecho de código faz o hash da senha fornecida usando bcrypt e, em seguida, cria um novo registro de usuário no banco de dados, armazenando o nome de usuário e a senha com hash. Se o registro for bem-sucedido, ele enviará uma resposta com uma mensagem de sucesso.
  2. Defina um controlador de login para gerenciar o processo de login do usuário:
    exports.loginUser = assíncrono (req, res) => {
    const { nome de usuário, senha } = req.body;

    tentar {
    const usuário = aguardam User.findOne({ nome de usuário });

    se (!do utilizador) {
    retornar res.status(404).enviar({ mensagem: 'Usuário não encontrado' });
    }

    const passwordMatch = aguardam bcrypt.compare (senha, usuário.senha);

    se (!passwordMatch) {
    retornar res.status(401).enviar({ mensagem: 'Credenciais de login inválidas' });
    }

    const carga útil = { ID do usuário: ID do usuário };
    const token = gerarToken (carga útil);
    res.cookie('símbolo', símbolo, { httpOnly: verdadeiro });
    res.status(200).json({ mensagem: 'Login com sucesso'});
    } pegar (erro) {
    console.log (erro);
    res.status(500).enviar({ mensagem: 'Ocorreu um erro ao fazer login' });
    }
    };

    Quando um usuário envia uma solicitação ao /login rota, eles devem passar suas credenciais de autenticação no corpo da solicitação. O código então verifica essas credenciais e gera um JSON Web Token. O token é armazenado com segurança em um cookie com o httpOnly sinalizador definido como verdadeiro. Isso impede que o JavaScript do lado do cliente acesse o token, protegendo contra possíveis ataques de script entre sites (XSS).
  3. Finalmente, defina uma rota protegida:
    exports.getUsers = assíncrono (req, res) => {
    tentar {
    const usuários = aguardam User.find({});
    res.json (usuários);
    } pegar (erro) {
    console.log (erro);
    res.status(500).enviar({ mensagem: 'Um erro ocorreu!!' });
    }
    };
    Ao armazenar o JWT em um cookie, as solicitações de API subsequentes do usuário autenticado incluirão automaticamente o token, permitindo que o servidor valide e autorize as solicitações.

Criar um middleware de autenticação

Agora que você definiu um controlador de login que gera um token JWT após uma autenticação bem-sucedida, defina as funções de autenticação de middleware que irão gerar e verificar o token JWT.

No diretório raiz, crie uma nova pasta, middleware. Dentro desta pasta, adicione dois arquivos: auth.js e config.js.

Adicione este código a config.js:

const cripto = exigir('cripto');

módulo.exportações = {
secretKey: crypto.randomBytes(32).para sequenciar('hex')
};

Esse código gera uma nova chave secreta aleatória toda vez que é executado. Você pode usar essa chave secreta para assinar e verificar a autenticidade dos JWTs. Depois que um usuário for autenticado com sucesso, gere e assine um JWT com a chave secreta. O servidor usará a chave para verificar se o JWT é válido.

Adicione o seguinte código em auth.js que define funções de middleware que geram e verificam os JWTs.

const jwt = exigir('jsonwebtoken');
const { chave secreta } = exigir('./config');

const gerarToken = (carga útil) => {
const token = jwt.sign (payload, secretKey, { expira em: '1h' });
retornar símbolo ;
};

const verificarToken = (req, res, próximo) => {
const token = req.cookies.token;

se (!símbolo) {
retornar res.status(401).json({ mensagem: 'Nenhum token fornecido' });
}

jwt.verify (token, secretKey, (err, decodificado) => {
se (err) {
retornar res.status(401).json({ mensagem: 'Token inválido' });
}

req.userId = decodificado.userId;
próximo();
});
};

módulo.exports = { gerarToken, verificarToken };

O gerarToken A função gera um JWT assinando uma carga útil usando uma chave secreta e definindo um tempo de expiração enquanto o VerifyToken A função serve como middleware para verificar a autenticidade e a validade de um token fornecido.

Definir as rotas da API

Crie um novo rotas/userRoutes.js arquivo no diretório raiz e adicione o seguinte código.

const expresso = exigir('expressar');
const roteador = expresso. Roteador();
const userControllers = exigir('../controllers/userControllers');
const {verificarToken} = exigir('../middleware/auth');
roteador.post('/api/registro', userControllers.registerUser);
roteador.post('/api/login', userControllers.loginUser);
router.get('/api/usuários',verifyToken, userControllers.getUsers);
módulo.exports = roteador;

Atualize seu ponto de entrada do servidor

Atualize seu server.js arquivo com o seguinte código.

const expresso = exigir('expressar');
const cors = exigir('cors');
const aplicativo = expresso();
const porta = 5000;
exigir('dotenv').config();
const conectarDB = exigir('./utils/db');
const cookieParser = exigir('analisador de cookies');

conectarDB();

app.use (express.json());
app.use (express.urlencoded({ estendido: verdadeiro }));
app.use (cors());
app.use (cookieParser());
const userRoutes = exigir('./routes/userRoutes');
app.use('/', userRoutes);

app.listen (porta, () => {
console.registro(`Servidor está escutando em http://localhost:${porta}`);
});

Para testar a API REST, ative o servidor de desenvolvimento e faça solicitações de API para os endpoints definidos:

node server.js

Protegendo as APIs REST do Node.js

Proteger APIs REST Node.js vai além de apenas usar JWTs, embora eles desempenhem um papel crucial na autenticação e autorização, é essencial adotar uma abordagem de segurança holística para proteger seu back-end sistemas. Juntamente com os JWTs, você também deve considerar a implementação de HTTPS para criptografar a comunicação, validação e sanitização de entrada e muitos outros.

Ao combinar várias medidas de segurança, você pode estabelecer uma estrutura de segurança robusta para o seu APIs REST Node.js e minimizam o risco de acesso não autorizado, violações de dados e outros problemas de segurança ameaças.