aut2fa/ blog

Como verificar número de telefone no cadastro com Node.js

Tutorial completo com Express para verificar o telefone do usuário no cadastro: envio do código, tela de confirmação, verificação e tratamento de erros.

Código Node.js com Express verificando o número de telefone de um usuário

Cadastro com telefone falso é dor de cabeça garantida: contas duplicadas, fraude, campanhas de marketing indo para o nada. A solução é verificar o número de telefone no cadastro com um código de uso único.

Neste tutorial vamos montar o fluxo completo com Node.js e Express, usando a API da aut2fa para enviar o código pelo WhatsApp.

O que vamos construir

  1. POST /cadastro/telefone – recebe o telefone e envia o código.
  2. POST /cadastro/verificar – recebe o código digitado e confirma o telefone.

Preparação

Crie uma conta na aut2fa, crie uma aplicação e copie a chave de teste (ak_test_…). No modo de teste nada é cobrado e o código gerado é sempre 000000.

npm init -y
npm i express
export AUT2FA_KEY="ak_test_…"

Usamos fetch nativo (Node 18+). Se preferir, há um SDK oficial: npm i @aut2fa/node.

Cliente da API

// aut2fa.js
const API = "https://api.aut2fa.com/v1";

async function call(path, body, idempotencyKey) {
  const headers = {
    Authorization: `Bearer ${process.env.AUT2FA_KEY}`,
    "Content-Type": "application/json",
  };
  if (idempotencyKey) headers["Idempotency-Key"] = idempotencyKey;

  const res = await fetch(`${API}${path}`, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
  });

  const data = await res.json().catch(() => ({}));
  return { status: res.status, data, retryAfter: res.headers.get("retry-after") };
}

export const enviar = (to, key) => call("/send", { to, locale: "pt-BR" }, key);
export const verificar = (id, code) => call(`/send/${id}/verify`, { code });

Rota de envio

// server.js
import express from "express";
import crypto from "node:crypto";
import { enviar, verificar } from "./aut2fa.js";

const app = express();
app.use(express.json());

// Em produção, use seu banco ou Redis
const pendentes = new Map();

app.post("/cadastro/telefone", async (req, res) => {
  const { telefone } = req.body;

  // Aceite só números brasileiros em formato E.164
  if (!/^\+55\d{10,11}$/.test(telefone)) {
    return res.status(400).json({ erro: "Telefone inválido" });
  }

  const key = crypto.randomUUID();
  const r = await enviar(telefone, key);

  if (r.status === 429) {
    return res.status(429).json({
      erro: "Aguarde para pedir outro código",
      tentarEm: Number(r.retryAfter),
    });
  }
  if (r.status !== 202) {
    return res.status(502).json({ erro: "Não foi possível enviar o código" });
  }

  const token = crypto.randomUUID();
  pendentes.set(token, { telefone, sendId: r.data.id });
  res.json({ token, expiraEm: r.data.expires_at });
});

Três detalhes importantes:

  • Validação do formato antes de chamar a API: barra lixo e números de outros países.
  • Idempotency-Key: se a requisição for repetida por timeout, a API devolve o envio original em vez de mandar um segundo código.
  • HTTP 429: a aut2fa bloqueia envios acima dos limites antes de enviar e informa no Retry-After quantos segundos esperar. Use isso na contagem regressiva do botão "reenviar".

Rota de verificação

app.post("/cadastro/verificar", async (req, res) => {
  const { token, codigo } = req.body;
  const pendente = pendentes.get(token);
  if (!pendente) return res.status(404).json({ erro: "Sessão expirada" });

  const r = await verificar(pendente.sendId, codigo);

  if (r.data.valid) {
    pendentes.delete(token);
    // marque o telefone como verificado no seu banco
    return res.json({ ok: true, telefone: pendente.telefone });
  }

  res.status(400).json({
    ok: false,
    tentativasRestantes: r.data.attempts_left,
  });
});

app.listen(3000);

O código vale 10 minutos e, depois de 5 tentativas erradas, o envio é bloqueado. Nesse caso, peça um novo código.

Testando

curl -X POST localhost:3000/cadastro/telefone \
  -H "Content-Type: application/json" \
  -d '{"telefone": "+5531999999999"}'

curl -X POST localhost:3000/cadastro/verificar \
  -H "Content-Type: application/json" \
  -d '{"token": "<token>", "codigo": "000000"}'

Indo para produção

  • Troque a chave ak_test_ pela ak_live_ (sempre em variável de ambiente).
  • Guarde as verificações pendentes no banco ou Redis.
  • Ative no painel os limites por aplicação: por minuto e por destinatário por hora.
  • Acompanhe no extrato o canal, o número que enviou e os horários de envio, entrega e leitura.

Conclusão

Com duas rotas e duas chamadas HTTP você tem verificação de telefone no cadastro, com proteção contra abuso e rastreio de entrega. Veja todos os campos na documentação e comece grátis.

Continue lendo