
Login sem senha com código no e-mail: como funciona e quando usar
Nesta página · 10 seções
Login sem senha por código no e-mail é um fluxo em que o usuário informa o endereço, recebe um código de 8 caracteres na caixa de entrada e o digita para entrar. Não há senha para escolher, guardar nem recuperar. Quem controla a caixa de entrada consegue entrar na conta, e é essa a prova que o fluxo verifica.
Como o fluxo funciona
O login tem duas chamadas, e a tela pode ser uma só.
Pedido do código. O app envia o e-mail para
POST /auth/code/start. O Auth gera um código de 8 caracteres no formatoABCD-EFGHe o manda por e-mail.Apresentação do código. O usuário digita o código, e o app envia o e-mail e o código para
POST /auth/code/verify. A resposta traz o token da sessão e os dados do usuário.
Algumas regras que valem para todo o fluxo:
| Regra | Valor |
|---|---|
| Validade do código | 10 minutos |
| Tentativas erradas | 5, depois o pedido é destruído |
| Código por pedido | Um só; um novo pedido substitui o anterior |
| Mensagem | Traz só o código, sem link |
O código não traz link de propósito. Um link precisaria de um endereço de retorno, e isso abre espaço para fixar a origem errada da aplicação ou para sequestrar um callback. Com um código digitado na mesma aba, não há destino para gravar nem retorno para atacar.
No SDK React, o componente <SignIn /> faz os dois passos na mesma rota, sem navegação no meio. No seu backend, o plugin do Elysia valida o token que chega e disponibiliza o usuário no contexto da rota.
A conta nasce na primeira entrada
Não existe tela de cadastro separada. Quando o código é apresentado pela primeira vez para um e-mail que não tem conta, o Auth cria a conta já verificada e com uma organização própria. Quem já tem conta apenas entra.
Isso tem uma consequência prática: você não precisa saber, antes de mostrar a tela, se o usuário é novo. A resposta é a mesma nos dois casos, e o fluxo de "criar conta" deixa de existir como etapa para o usuário.
O que fica depois do login: a sessão
Depois da verificação, o token da sessão vale o que o dono da aplicação configurou na aba Sessão, com 7 dias como padrão. O AuthProvider do SDK guarda o token, confere a validade a cada 4 minutos e, quando faltam menos de 5 minutos para expirar, renova o token sem pedir código de novo. Se o usuário abre o app em outra aba, o logout ou o login se propaga para todas elas.
Do lado do servidor, o backend valida o token localmente via JWKS, sem ir ao Auth a cada requisição. O usuário fica disponível no contexto da rota:
.get('/profile', ({ user }) => ({ id: user.id, email: user.email }))
A chave que você deve guardar para o usuário é o id dele, e não o e-mail. O e-mail pode mudar, e quando um administrador troca o endereço, a troca zera a verificação e o próximo código que chega no endereço novo a confirma de novo.
Organizações e papéis
Cada usuário pertence a uma aplicação, e a aplicação pode ter organizações de clientes. Um usuário dono ou administrador da organização pode adicionar outro usuário que já tem conta, com um papel. Não há convite por e-mail: a pessoa precisa ter entrado antes.
Um cuidado importante: o token ainda não carrega as organizações nem os papéis. O JWT traz identidade e sessão, mas a relação entre o usuário e a organização fica no seu próprio banco. Guarde o user.id como chave estrangeira e aplique a autorização por organização nas suas rotas. Não dependa de user.memberships ou user.role no token, porque hoje esses campos não estão lá.
Para uma verificação simples de quem entra no app, o <Protect> do SDK separa logado de deslogado. Distinguir um administrador de um membro comum é tarefa da sua aplicação.
O que fica pronto e o que não existe
O Auth entrega, sem você escrever: o envio do código, a validade e o limite de tentativas, a criação da conta na primeira entrada, a renovação da sessão, o logout sincronizado entre abas, a listagem e a revogação de sessões em outros dispositivos, e a validação do token no backend.
Não existe, por enquanto:
troca de e-mail pelo próprio usuário (só um administrador troca, pelo painel);
convite de membro por e-mail;
senha, nem como alternativa.
Login social com Google já está disponível. As credenciais são do próprio dono da aplicação, configuradas no painel, e o botão aparece sozinho no <SignIn />.
Quando usar
Login sem senha faz sentido quando o seu usuário entra pouco e não quer lembrar de mais uma senha, quando você não quer ser responsável por armazenar senhas, e quando a prova de posse do e-mail já basta para o seu caso. Em apps onde o usuário entra todo dia, a sessão de 7 dias reduz a frequência de códigos a quase zero.
Se o seu produto exige senha por política interna ou por norma do setor, este fluxo não atende e você precisa de outra solução.
Perguntas frequentes
O código pode ser reutilizado?
Não. Cada código vale uma vez. Ao ser apresentado com sucesso, o pedido é consumido e não pode ser usado de novo.
O que acontece se o usuário não receber o e-mail?
Ele pode pedir um novo código. O novo pedido substitui o anterior, então só o código mais recente funciona. Se o envio falhar do lado do serviço, o pedido responde com erro temporário (503) e o app pode tentar de novo depois.
Dá para usar isso num app sem tela, como um agente ou um script?
Sim, há uma variante para quem não consegue ler o e-mail na hora: o pedido gera um código de dispositivo, que é consultado por polling até alguém apresentar o código do e-mail. Quem está no navegador deve usar o fluxo normal, que resolve numa chamada só.
Para continuar lendo
Como um agente de IA faz login no seu app: OAuth 2.1 e o passo humano
E-mail transacional pelo seu domínio: verificação, eventos e supressão
Entrar sem senha no seu app
Quem entra no seu app com um código no e-mail não precisa lembrar de senha, e você não precisa guardá-la. O Auth cuida do envio, da sessão e das organizações, e o que sobra para o seu código é a autorização de cada rota.
Fontes
Quem escreveu
Continue lendo
Como um agente de IA faz login no seu app: OAuth 2.1 e o passo humanoMais sobre Auth · · 5 min
Guardar dados e arquivos do app sem migration nem credencial de nuvemMais recente · · 5 min
Como cobrar assinatura no seu app sem escrever webhookMais recente · · 4 min
E-mail transacional pelo seu domínio: verificação, eventos e supressãoMais recente · · 6 min
Função serverless com agendamento: código sob demanda com um endpointMais recente · · 6 min
Onde hospedar uma SPA em React ou Vite sem quebrar as rotasMais recente · · 5 min