Magic Link

Autenticacao sem senha via token por email.

Como funciona

O Magic Link permite login sem senha. O fluxo e:

  1. Usuario informa seu email em POST /api/auth/magic-link/send
  2. Um token unico (nanoid, 32 caracteres) e gerado com expiracao
  3. Um link e criado: http://localhost:3000/auth/verify?token=abc123...
  4. O link e enviado por email (requer SMTP configurado)
  5. Usuario clica no link, que chama GET /api/auth/magic-link/verify?token=abc123
  6. O token e validado e consumido (uso unico)
  7. Um JWT e gerado para o usuario

Arquivos gerados

O arquivo principal e magic-link.service.ts, compartilhado por todos os backends:

import { nanoid } from 'nanoid';

const EXPIRY_MINUTES = Number(process.env.MAGIC_LINK_EXPIRY_MINUTES) || 15;
const APP_URL = process.env.APP_URL || 'http://localhost:3000';

export function generateMagicLink(email: string): { token: string; url: string } {
  const token = nanoid(32);
  const expiresAt = new Date(Date.now() + EXPIRY_MINUTES * 60 * 1000);

  tokens.set(token, { token, email, expiresAt });

  const url = `${APP_URL}/auth/verify?token=${token}`;
  return { token, url };
}

export function verifyMagicLinkToken(token: string): { valid: boolean; email?: string } {
  const entry = tokens.get(token);
  if (!entry) return { valid: false };
  if (entry.expiresAt < new Date()) {
    tokens.delete(token);
    return { valid: false };
  }
  tokens.delete(token); // uso unico
  return { valid: true, email: entry.email };
}

Alem do service, e gerado um controller (NestJS) ou router (Express/Fastify) com as rotas /send e /verify.

Dependencia de SMTP

Para que o magic link funcione em producao, voce precisa do servico de email (SMTP) habilitado. No modo de desenvolvimento, o link e logado no console.

# Variaveis de ambiente necessarias
MAGIC_LINK_EXPIRY_MINUTES=15
APP_URL=http://localhost:3000

# Se SMTP estiver habilitado:
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=seu-email@gmail.com
SMTP_PASS=sua-app-password

Nota: Em desenvolvimento, o token e URL sao printados no console do servidor para teste rapido.

Armazenamento de tokens

Por padrao, os tokens sao armazenados em um Map em memoria. Em producao, voce deve migrar para:

  • Redis — com TTL automatico (recomendado)
  • Banco de dados — tabela/collection de tokens com campo expiresAt