DEV Community

Bruno Mestres
Bruno Mestres

Posted on

Construindo uma API segura e eficiente com @fastify/jwt e @fastify/mongodb

Ultimamente tenho utilizado bastante o Fastify em meus projetos pessoais, recentemente descobri diversas funcionalidades através de plugins oficiais.

Eles são leves, eficientes e, o melhor de tudo, encaixam perfeitamente no ecossistema do Fastify.

Então resolvi criar um projeto prático com autenticação e persistência, utilizando o JWT e o MongoDB.

Plugins usados no projeto:

⚒️ O @fastify/jwt é um plugin oficial que simplifica a autenticação com JSON Web Tokens. Com ele, dá pra:

  • Gerar tokens JWT de forma rápida.
  • Verificar tokens automaticamente nas rotas protegidas.

⚒️ @fastify/mongodb: Plugin oficial do Fastify para integração com o banco de dados MongoDB.

  • Ele se encarrega de gerenciar a conexão com o MongoDB de forma eficiente, sem que eu precise ficar configurando drivers manualmente.

Os plugins seguem uma interface padrão. Basta registrá-los com fastify.register(), definir algumas configurações e pronto.

Depois disso posso, acessar o banco diretamente com fastify.mongo e o módulo do jwt com o fastify.jwt.

Também criei um decorator para anexar apenas as rotas que seriam protegidas, onde ele verificará o token passado no cabeçalho.

import Fastify from "fastify";
import mongodb from "@fastify/mongodb";
import jwt from "@fastify/jwt";
import { config } from "./constants.ts";
import * as bcrypt from "bcrypt";

const fastify = Fastify();

type RequestUser = {
  username: string;
  email: string;
  password: string;
};

fastify.register(mongodb, {
  forceClose: true,
  url: config.MONGO_URL,
});

fastify.register(jwt, {
  secret: "supersecret",
});

fastify.post("/signup", async (req, reply) => {
  const salt = 10;
  const { email, password, username } = req.body as RequestUser;

  const data = {
    username,
    email,
    password: await bcrypt.hash(password, salt),
  };

  const user = await fastify.mongo.client.db("plugins").collection("users").insertOne(data);

  reply.send({ user })
});

fastify.decorate("auth", async (request, reply) => {
  try {
    await request.jwtVerify();
  } catch (err) {
    reply.send(err);
  }
});

fastify.post("/signin", (req, reply) => {
  // some code
  const body = req.body;
  const token = fastify.jwt.sign({ body });
  console.log(token);
  reply.send({ token });
});

fastify.get("/", { onRequest: [fastify.auth] }, async (req, reply) => {
  const users = fastify.mongo?.client.db("plugins").collection("users").find();

  const data: any = [];

  for await (const doc of users) {
    data.push(doc);
  }
  return data;
});

fastify.listen({ port: 3333 }, (err) => {
  if (err) process.exit(1);

  console.log("Running server");
});

Enter fullscreen mode Exit fullscreen mode

Top comments (0)