Toda vez que alguém pergunta "qual método de autenticação em duas etapas eu devo usar", a resposta padrão que circula por aí é "TOTP é mais seguro, use sempre". Tecnicamente correto, mas incompleto. Segurança não é a única variável que importa quando você está desenhando um fluxo de autenticação — taxa de conversão, custo operacional e alcance geográfico do seu usuário pesam tanto quanto, e ignorar isso costuma gerar decisão de arquitetura que parece certa no papel e falha na adoção real.
Passei por essa decisão em mais de um projeto, e o que aprendi é que não existe resposta única — existe a resposta certa pro contexto específico do produto. Vou tentar destrinchar os trade-offs reais de cada opção.
SMS: o padrão de fato, com todos os problemas conhecidos
SMS ganhou o mercado não porque é o método mais seguro, mas porque é o de menor fricção. Não exige instalar nada, funciona em qualquer celular com sinal, e o usuário já entende o fluxo sem precisar de explicação — recebeu código, digitou, pronto.
Os problemas são conhecidos: vulnerabilidade a SIM swap, dependência de infraestrutura de operadora que varia de confiabilidade por região, custo por envio que escala com volume, e latência de entrega que pode variar de segundos a minutos dependendo do país. Pra produtos com base de usuário internacional, essa variação de confiabilidade entre países é o problema mais subestimado — o que funciona perfeitamente testando com número local pode falhar silenciosamente com usuário de outro continente.
async function sendSmsOtp(phone, code) {
try {
await smsProvider.send({
to: phone,
body: `Seu código: ${code}`,
});
return { success: true };
} catch (err) {
// não assuma que falha é rara — trate como caminho esperado
logDeliveryFailure(phone, err);
return { success: false, fallbackAvailable: true };
}
}
Quando faz sentido: produto com base de usuário ampla e heterogênea, onde exigir app extra reduziria conversão de cadastro de forma significativa. Praticamente qualquer produto B2C de massa se encaixa aqui, ao menos como opção padrão inicial.
Chamada de voz: o fallback subestimado
Chamada de voz automatizada, lendo o código em voz alta, é frequentemente tratada como recurso secundário — e é mesmo, na maioria dos casos. Mas ela resolve um problema específico que SMS não resolve bem: cenários onde a entrega de texto está falhando (filtro de spam de operadora, número recém-portado com problema de roteamento, país com bloqueio de sender ID) mas a linha ainda recebe chamada normalmente.
Implementar como fallback, não como método primário, costuma ser a decisão certa — o custo por chamada é geralmente mais alto que SMS, e a experiência (atender, ouvir, digitar) tem mais fricção que ler uma mensagem.
async function sendOtpWithFallback(phone, code) {
const smsResult = await sendSmsOtp(phone, code);
if (!smsResult.success) {
await voiceProvider.call({
to: phone,
say: `Seu código de verificação é ${code.split('').join(', ')}`,
});
}
}
Quando faz sentido: como camada de resiliência atrás de SMS, não como substituto. Produtos com usuário em regiões de entrega de SMS historicamente instável se beneficiam de ativar isso desde o lançamento, não só depois que o problema aparecer.
App autenticador (TOTP): mais seguro, mais fricção de adoção
Google Authenticator, Authy e afins geram código localmente, sem depender de rede de telefonia, o que elimina de uma vez os riscos de interceptação e SIM swap. Do ponto de vista puramente técnico, é superior. O problema é adoção: exigir que o usuário instale um app separado, escaneie QR code e entenda o conceito de código temporário é fricção real, que produtos B2C de massa sentem na taxa de conversão de cadastro.
import { authenticator } from 'otplib';
function generateTotpSecret() {
return authenticator.generateSecret();
}
function verifyTotp(token, secret) {
return authenticator.verify({ token, secret });
}
Quando faz sentido: produtos onde o usuário já tem maior tolerância a fricção de segurança em troca de confiança — fintech, ferramenta corporativa, produto B2B técnico. Também faz sentido oferecer como opção avançada opcional em qualquer produto, pro usuário que já entende o valor e quer ativar por conta própria.
O erro comum: escolher um método só, pra sempre
O padrão que vejo mais gerar problema não é escolher o método errado — é tratar a escolha como definitiva e única, sem plano de evolução. Produto lança só com SMS, cresce, ganha usuário internacional, e só aí descobre que precisa de voz como fallback e TOTP como opção avançada. Nada impede desenhar a arquitetura de autenticação já pensando em múltiplos métodos desde o início, mesmo que só um esteja ativo no lançamento.
const authMethods = {
sms: { primary: true, fallback: false },
voice: { primary: false, fallback: true },
totp: { primary: false, fallback: false, optIn: true },
};
async function sendVerification(user, method = 'sms') {
const config = authMethods[method];
if (!config) throw new Error('Método não suportado');
return method === 'sms' ? sendOtpWithFallback(user.phone, code) : null;
}
Estruturar assim desde cedo — mesmo com só um método ativo — evita reescrever o fluxo inteiro quando a necessidade de adicionar outro método aparecer, e ela costuma aparecer mais cedo do que se imagina.
Testando os três antes de decidir
Uma coisa que ajuda bastante antes de bater o martelo é simular os três métodos com usuário de teste real, não só com o seu próprio número do seu próprio país. Pra isso, sem precisar arranjar chip físico de várias regiões, dá pra usar número virtual — a numerovirtual.net tem cobertura de vários países que serve bem pra esse tipo de teste, testando entrega de SMS e de chamada de voz de fato, em vez de assumir que vai funcionar igual em todo lugar só porque funcionou no seu teste local.
Não existe "o melhor", existe o adequado ao contexto
Se seu produto é B2C de massa, comece com SMS e adicione voz como fallback assim que tiver volume suficiente pra justificar o custo. Se é B2B técnico ou lida com dado sensível, considere TOTP como padrão desde o início, com SMS como opção de recuperação. Se atende usuário internacional, teste entrega em múltiplos países antes de assumir que o comportamento vai ser uniforme.
A pergunta certa nunca é "qual é o método mais seguro" isolado de contexto — é "qual combinação de segurança, custo e fricção faz sentido pro usuário que meu produto realmente tem".
Top comments (0)