DEV Community

João Neto for Guarapi

Posted on • Edited on

Implementando um Plugin de Autenticação para Guarapi

Olá!

Gostaria de compartilhar uma Prova de Conceito (POC) de um plugin de autenticação em desenvolvimento para o Guarapi. Este plugin visa oferecer funcionalidades de autenticação e renovação de tokens JWT.

Para mais informações e para colaborar, acesse nosso Discord Guarapi Development e confira o GitHub do Guarapi.

Aqui está uma breve amostra do código do plugin:

import { Plugin, Request } from 'guarapi';
import { Methods } from 'guarapi/dist/lib/router';
import { sign } from 'jsonwebtoken';

interface SingConfig<P extends { sub: string | number }> {
  route: string;
  getJWTPayload: (req: Request) => Promise<P>;
}

export interface GuarapiAuthPluginConfig<P extends { sub: string | number }> {
  signIn?: SingConfig<P>;
  refreshToken?: SingConfig<P>;
  salt: string;
  tokenExpiresIn: string;
  refreshTokenExpiresIn: string;
  issuer: string;
  audience: string;
}

export default function guarapiAuthPlugin<P extends { sub: string | number }>(
  guarapiAuthPluginConfig: GuarapiAuthPluginConfig<P>,
) {
  const { salt, audience, issuer, tokenExpiresIn, refreshTokenExpiresIn, signIn, refreshToken } =
    guarapiAuthPluginConfig;

  const routesMap: Record<string, SingConfig<P> | undefined> = {
    [signIn?.route || '']: signIn,
    [refreshToken?.route || '']: refreshToken,
  };

  async function getTokens(req: Request, route: SingConfig<P>) {
    const { sub, ...jwtPayload } = await route.getJWTPayload(req);

    return {
      token: sign({ sub, ...jwtPayload }, salt, {
        expiresIn: route === signIn ? tokenExpiresIn : refreshTokenExpiresIn,
        audience,
        issuer,
      }),

      refreshToken: sign({ sub, ...jwtPayload }, salt, {
        expiresIn: refreshTokenExpiresIn,
        audience,
        issuer,
      }),
    };
  }

  const plugin: Plugin = (app) => {
    app.use(async (req, res, next) => {
      const route = routesMap[req.url || ''];
      const method = req.method?.toLocaleLowerCase();

      if (route && method === Methods.POST) {
        const tokens = await getTokens(req, route);
        res.json(tokens);
        return;
      }

      next();
    });

    return {
      name: 'guarapiAuthPlugin',
    };
  };

  return plugin;
}
Enter fullscreen mode Exit fullscreen mode

Este plugin permite configurar rotas de autenticação e renovação de tokens JWT, adaptáveis às necessidades do projeto. Ele utiliza o pacote jsonwebtoken para gerar os tokens com base nas configurações fornecidas.

A configuração básica para este plugin é a seguinte:

import { Guarapi, bodyParserPlugin, middlewarePlugin } from 'guarapi';
import guarapiAuthPlugin, { GuarapiAuthPluginConfig } from './guarapi-auth-plugin';

interface PayloadRequest {
  userId: string;
}

export default async function initPlugins(app: Guarapi) {
  const authConfig: GuarapiAuthPluginConfig<{ sub: string; userId: string }> = {
    signIn: {
      route: '/auth/signin',
      getJWTPayload: async (req) =>
        Promise.resolve({ sub: 'teste', userId: (req.body as PayloadRequest)?.userId }),
    },
    refreshToken: {
      route: '/auth/refresh',
      getJWTPayload: async (req) =>
        Promise.resolve({ sub: 'teste', userId: (req.body as PayloadRequest)?.userId }),
    },
    audience: 'teste',
    issuer: 'issuer-1',
    salt: 'secret',
    refreshTokenExpiresIn: '24h',
    tokenExpiresIn: '1h',
  };

  app.plugin(bodyParserPlugin);
  app.plugin(middlewarePlugin);
  app.plugin(guarapiAuthPlugin(authConfig));
}
Enter fullscreen mode Exit fullscreen mode

Estou buscando feedback da comunidade sobre a estrutura, a lógica de funcionamento e possíveis melhorias que podem ser implementadas neste plugin. Sintam-se à vontade para discutir e compartilhar suas opiniões, sugestões ou dúvidas relacionadas a esta POC.

Agradeço antecipadamente por qualquer contribuição ou feedback que possam oferecer!

Nossas redes:

Plataforma Link
Reddit Guarapi Subreddit
Daily.dev Daily.dev Invite
Discord Discord Invite
Repositório Guarapi no GitHub

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay