E-mails de redefinição de senha confiáveis (e que chegam à caixa de entrada)

Crie um fluxo seguro de redefinição de senha: tokens de uso único, expiração curta, sem enumeração de contas, um modelo de e-mail claro e confirmação da troca.

O e-mail de redefinição de senha é a chave mestra do seu produto. Quem conseguir lê-lo pode assumir a conta, e é por isso que os invasores o têm como alvo e os usuários aprenderam a desconfiar dele.

Um bom fluxo de redefinição precisa ser seguro o bastante para resistir a esses ataques e claro o bastante para que usuários reais confiem nele em poucos segundos. Este guia percorre os dois aspectos, desde o momento em que alguém clica em “Esqueceu a senha?” até o e-mail de confirmação depois da troca.

O fluxo em resumo

  1. O usuário informa o e-mail na página Esqueceu a senha.
  2. Seu app sempre mostra a mesma mensagem, exista a conta ou não.
  3. Se a conta existir, você cria um token de uso único e envia um link de redefinição por e-mail.
  4. O usuário abre o link, escolhe uma nova senha e o token é consumido.
  5. Você encerra as outras sessões do usuário e envia um e-mail de “sua senha foi alterada”.

Passo 1: não revele quem tem conta

Depois que o formulário for enviado, responda sempre com o mesmo texto:

Se existir uma conta para ada@example.com, enviamos um link para redefinir sua senha. Ele expira em 30 minutos.

Mostrar “Nenhuma conta com esse e-mail” diz a qualquer pessoa com uma lista de endereços exatamente quais deles usam o seu produto. Mantenha também o tempo de resposta parecido: faça a busca da conta e o envio do e-mail em segundo plano, para que a página não responda perceptivelmente mais rápido para endereços desconhecidos.

Passo 2: crie um token forte e de uso único

O token no link precisa ser longo, aleatório e impossível de adivinhar:

import { randomBytes, createHash } from 'node:crypto';

const token = randomBytes(32).toString('base64url');            // goes in the email
const tokenHash = createHash('sha256').update(token).digest('hex'); // goes in the database

await db.passwordResets.upsert({
  userId: user.id,
  tokenHash,
  expiresAt: new Date(Date.now() + 30 * 60 * 1000), // 30 minutes
});

As regras:

  • Armazene apenas um hash do token, para que um vazamento do banco de dados não entregue links de redefinição válidos.
  • Um token ativo por usuário. Emitir um novo substitui o antigo.
  • Expiração curta: de 15 a 60 minutos é o mais comum.
  • Uso único. Exclua o token assim que a senha for alterada.
  • Invalide o token se, nesse meio-tempo, o usuário fizer login com sucesso ou mudar o endereço de e-mail.

Passo 3: envie o e-mail imediatamente

O usuário está esperando, então envie dentro da requisição, e não em um job em lote:

import os
import requests

def send_reset_email(user, token):
    link = f"https://app.yourco.com/reset-password/{token}"
    res = requests.post(
        "https://backend.inbixio.com/api/send-email/",
        headers={"X-API-Key": os.environ["INBIXIO_API_KEY"]},
        json={
            "to_email": user.email,
            "subject": "Reset your YourApp password",
            "message": render_reset_template(name=user.first_name, link=link, minutes=30),
        },
        timeout=10,
    )
    res.raise_for_status()

Envie a partir de um endereço dedicado e autenticado, como security@yourco.com. Na Inbixio, conecte essa caixa de e-mail como um servidor de e-mail próprio e dê ao serviço de autenticação uma chave de API vinculada a ele, para que os e-mails de redefinição venham do endereço que os usuários esperam. Se algum dia você remover esse servidor, vincule a chave de novo. Veja segurança de chaves de API para configurar isso.

Passo 4: escreva um e-mail confiável

E-mails de phishing imitam redefinições de senha mais do que qualquer outra mensagem. Faça o seu ser inconfundível:

  • Assunto: simples e específico, por exemplo “Redefina sua senha do YourApp”. Sem urgência, sem pontos de exclamação.
  • Um único botão claro, mais o link completo em texto para clientes que bloqueiam botões.
  • A validade: “Este link expira em 30 minutos.”
  • Contexto: quando a solicitação foi feita e, se você tiver essa informação, de qual navegador ou cidade.
  • O que fazer se não tiver sido a pessoa: “Se você não pediu para redefinir sua senha, pode ignorar este e-mail. Sua senha não será alterada.”
  • Nenhum outro link, imagem ou promoção. Quanto menos links, mais fácil é verificar.
<div style="font-family:system-ui,sans-serif;max-width:520px;margin:auto;color:#111;line-height:1.5">
  <p>Hi Ada,</p>
  <p>We received a request to reset the password for your YourApp account.</p>
  <p style="margin:28px 0">
    <a href="https://app.yourco.com/reset-password/TOKEN"
       style="background:#584efe;color:#fff;padding:12px 20px;border-radius:8px;text-decoration:none;font-weight:600">
      Choose a new password
    </a>
  </p>
  <p>This link expires in 30 minutes and can only be used once.</p>
  <p>If you didn't ask to reset your password, you can safely ignore this email.</p>
  <p style="color:#666;font-size:13px">Button not working? Paste this link into your browser:<br>
    https://app.yourco.com/reset-password/TOKEN</p>
</div>

Quando o usuário abrir o link:

  • Busque o hash do token, verifique se ele não expirou e mostre o formulário de “nova senha”. Não faça o login do usuário ainda.
  • Mantenha o token fora de requisições a terceiros. Adicione <meta name="referrer" content="no-referrer"> à página de redefinição e não carregue scripts de analytics ou de anúncios nela, para que o token na URL não vaze pelos headers de referrer.
  • No envio do formulário, valide a nova senha com as suas regras de senha, gere o hash dela com um algoritmo lento (bcrypt, scrypt ou Argon2), exclua o token e encerre todas as outras sessões.

Passo 6: confirme a alteração

Sempre envie uma confirmação curta depois de uma troca de senha:

Sua senha do YourApp foi alterada em 28 de outubro às 14:32 UTC. Se foi você, não é preciso fazer mais nada. Se não foi, proteja sua conta imediatamente.

Este e-mail é o alarme do usuário caso outra pessoa tenha entrado, então nunca deixe de enviá-lo.

Garanta que ele chegue

Um e-mail de redefinição na caixa de spam é um ticket de suporte. Antes do lançamento:

  • configure SPF, DKIM e DMARC para o seu domínio de envio,
  • teste com endereços do Gmail e do Outlook e confira se os headers mostram PASS, e
  • acompanhe a taxa de Failed Deliveries (entregas com falha) no seu painel da Inbixio depois do deploy.

Checklist

  • A mesma resposta para e-mails existentes e desconhecidos
  • Token aleatório de 32 bytes, com apenas o hash armazenado
  • Expiração de 15–60 minutos, uso único, um token ativo por usuário
  • Envio imediato a partir de um remetente dedicado e autenticado
  • Modelo claro: um botão, link em texto, validade, linha de “não foi você?”
  • Nenhum script de terceiros na página de redefinição; referrer desativado
  • Outras sessões encerradas e e-mail de confirmação enviado depois da troca

Envie com a Inbixio

Conecte seu próprio servidor SMTP, crie uma chave de API com permissões restritas e envie de qualquer linguagem com uma única requisição HTTPS.

Criar conta Ver preços