Documentação
ReferênciaSDK JavaScriptNamespacesauth.challenges

auth.challenges

O passo entre "credenciais aceitas" e "sessão emitida".

Um desafio é o que volta quando a plataforma precisa de mais uma coisa antes de emitir uma sessão — um OTP, um código TOTP, uma confirmação de sudo. Você raramente cria um: signIn, signUp e sessions.sudo() devolvem um quando o ambiente ou os fatores da pessoa exigem.

Todo desafio é de vida curta, tem um propósito só, e é limitado a quatro tentativas. No quarto código errado o desafio é fechado no servidor e novas verificações falham com action_verification_failed — a pessoa precisa começar o fluxo de novo em vez de continuar chutando.

O formato

tokenstring | nullRequired

De vida curta, e a única alça que você tem sobre o desafio. Leve-o até o verify(). Ele não é o token de sessão e não pode ser usado como tal. É null quando preferred é link: não há código para verificar.

preferredChallengeSubjectRequired

Qual método apresentar primeiro. A plataforma escolhe — você renderiza.

totpUm app autenticador. Escolhido sempre que a pessoa tem um.
sms_otpUm código enviado por SMS.
email_otpUm código enviado por e-mail.
recovery_codesUm dos códigos salvos no cadastro do fator.
link

Um link foi enviado por e-mail. Não há nada a coletar — mostre "confira seu e-mail" em vez de um campo de código.

factorsAuthMethod[]Optional

As alternativas que esta pessoa de fato possui. É com isso que se monta um link de "tentar de outro jeito" — não ofereça métodos que ela não cadastrou.

identifierstringOptional

Já vem mascarado pela plataforma — u***@example.com. Pode ser renderizado como está, e é por isso que você não precisa do endereço real na tela de verificação.

subjectChallengeSubjectRequired

Por que o desafio foi emitido.

sign_upConfirmando uma conta nova.
verify_pending_userConfirmando uma conta que nunca foi ativada.
sign_in_with_otpEntrada sem senha.
mfaUm segundo fator depois da senha.
sudoReconfirmando identidade para uma ação sensível.
add_emailAdicionando uma identidade de e-mail a uma conta existente.
add_phoneAdicionando uma identidade de telefone.
expires_innumberOptional

Milissegundos até o desafio expirar. Configurado por ambiente e por método, então não cravar uma contagem regressiva no código.

O subject é o que permite uma tela só atender todos os fluxos: o mesmo campo de código pode finalizar um cadastro, um passo de MFA ou uma elevação de sudo, e o subject diz qual texto mostrar e para onde mandar a pessoa depois.


verify

verify({ token, code }) → Authenticated

Envia o código que a pessoa digitou. É a chamada que encerra o fluxo.

const { data, error } = await nulvless.auth.challenges.verify({
  token: challenge.token,
  code,
});
tokenstringRequired

Vindo do objeto Challenge.

codestringRequired

O que quer que a pessoa tenha digitado. Um código de recuperação vai neste mesmo campo — não há chamada separada para ele, e a plataforma decide contra qual fator verificar a partir do próprio desafio.

Devolve Authenticated — o mesmo formato que o signIn devolve. Em caso de sucesso o SDK guarda a sessão automaticamente, então um verify bem-sucedido deixa o client autenticado sem trabalho adicional.

Um código errado conta no orçamento de quatro tentativas. A quarta falha fecha o desafio, e o erro muda de uma rejeição comum para action_verification_failed. Distinga os dois na sua interface: o primeiro diz para a pessoa redigitar, o último diz para recomeçar.

O auth.verifyChallenge é a mesma operação no client de topo. Use o que ler melhor onde você está.


get

get(token) → Challenge

Lê o estado atual de um desafio sem consumir uma tentativa.

const { data: challenge } = await nulvless.auth.challenges.get(token);
tokenstringRequired

O token do desafio.

O caso para o qual isso existe: a pessoa recarrega a página de verificação, ou abre o link do e-mail em outro dispositivo. Você tem o token na URL mas nenhuma ideia se o desafio ainda está aberto. Ler antes permite mostrar um estado de expirado em vez de coletar um código que não pode funcionar.


change

change({ token, type, factor_id }) → { challenge }

Troca um desafio já em andamento para outro método, sem reiniciar a entrada.

const { data } = await nulvless.auth.challenges.change({
  token: challenge.token,
  type: 'email_otp',
});

// O novo desafio substitui o antigo.
setChallenge(data.challenge);
tokenstringRequired

Do desafio atualmente em andamento.

typeMFAMethodRequired

O método para o qual mudar. Repare que o campo é type, não method.

totpNada é enviado — o app já gera os códigos.
sms_otpEnvia um código novo por SMS.
email_otpEnvia um código novo por e-mail.
recovery_codesNada é enviado.
factor_idstringOptional

Só para sms_otp. Qual fator SMS recebe o código — um id de challenge.factors. Por padrão, o fator SMS mais antigo.

É isso que sustenta o "tentar de outro jeito" — quem está sem o autenticador migra para um código por e-mail sem voltar à tela de senha.

Duas coisas a tratar:

  • Volta um desafio novo, com um token novo. Substitua o que você segurava, ou o próximo verify vai falhar contra um desafio que não vale mais.
  • Mudar para um método de OTP envia mensagem, então entra no mesmo limite de taxa de qualquer outro envio de verificação. Mudar para totp ou recovery_codes não envia nada e não é limitado.

Ofereça apenas os métodos listados em challenge.factors.


create

create({ type, factor_id }) → { challenge }

Inicia um desafio diretamente, para um método que você nomeia.

const { data } = await nulvless.auth.challenges.create({ type: 'totp' });
typeMFAMethodRequired

Com qual método desafiar.

factor_idstringOptional

Só para sms_otp. Qual fator SMS recebe o código — um id de factors.list(). Por padrão, o fator SMS mais antigo.

Um desafio totp aceita o código de qualquer app autenticador do usuário. Para sms_otp, passe factor_id para escolher o telefone:

const { data } = await nulvless.auth.challenges.create({ type: 'sms_otp', factor_id });

Diferente do resto deste namespace, o create exige uma sessão autenticada — ele desafia o usuário atual. Não faz parte da entrada, onde ainda não existe sessão.

Você precisa disso bem menos do que parece. Entrada, cadastro e sudo já devolvem um desafio; recorra ao create quando o seu próprio produto quiser reconfirmar alguém no meio da sessão por um motivo que a plataforma desconhece.

O link não é válido aqui — ele é um valor de preferred que a plataforma escolhe durante o cadastro, não um método que você possa pedir.

Próximos

Nesta página