A integração funcionava, alguém ligou o 2FA no admin e o script que pegava token começou a devolver 400. A mensagem é essa: Please use the 2fa provider-specific endpoints to obtain a token.
Isso não é bug e não é excesso de zelo. O módulo de 2FA registra uma rota com a mesma URL do endpoint clássico e substitui o serviço por trás dela. O caminho antigo deixou de existir na prática.
Por que o endpoint antigo falha
Se você abrir o etc/webapi.xml do Magento_TwoFactorAuth, a primeira rota declarada é justamente /V1/integration/admin/token, apontando para uma interface própria do módulo. A implementação valida usuário e senha, descarta o token que sairia dali e lança exceção.
Como é uma LocalizedException, o processador de erro da Web API responde 400 Bad Request com a mensagem e mais um bloco parameters. E é aí que está o presente: o campo active_providers vem preenchido com os provedores que aquele usuário já ativou. O próprio erro te diz para onde ir.
Existem outras duas mensagens possíveis no mesmo endpoint, e vale saber diferenciar:
- Please ask an administrator with sufficient access to configure 2FA first — nenhum provedor de 2FA foi habilitado na loja.
- You are required to configure personal Two-Factor Authorization in order to login. Please check your email. — o provedor existe, mas esse usuário ainda não configurou o dele, e o Magento acabou de mandar o e-mail de configuração.
O endpoint certo, por provedor
Cada provedor tem a sua rota, todas com anonymous como recurso, ou seja, sem token prévio:
| Provedor | Endpoint (POST) |
|---|---|
| Google Authenticator | /V1/tfa/provider/google/authenticate |
| Authy | /V1/tfa/provider/authy/authenticate |
| Duo Security | /V1/tfa/provider/duo_security/authenticate |
| Chave U2F | /V1/tfa/provider/u2fkey/verify |
O do Google, que é o mais usado, recebe três campos: username, password e otp.
curl -sS -X POST "https://sualoja.com.br/rest/V1/tfa/provider/google/authenticate" \
-H "Content-Type: application/json" \
-d '{"username":"api.erp","password":"senha","otp":"123456"}'A resposta é o token entre aspas, do mesmo jeito que o endpoint antigo devolvia. Daí em diante nada muda: Authorization: Bearer <token> nas chamadas seguintes.
Se o usuário ainda não ativou o Google Authenticator, o par /V1/tfa/provider/google/configure e /V1/tfa/provider/google/activate faz a configuração inicial pela API. Eles trabalham com um tfaToken, não com usuário e senha.
OTP não serve para integração
Resolvido o erro, vem a pergunta que interessa: como é que o ERP digita um código de seis dígitos que muda a cada 30 segundos?
Não digita. Dá pra gerar o TOTP dentro do middleware a partir do segredo compartilhado, e funciona, mas você acabou de guardar o segundo fator no mesmo lugar que guarda a senha — o 2FA virou enfeite. Eu não faço isso em cliente.
O caminho certo é não usar token de admin nessa integração. Crie uma integração em System > Extensions > Integrations, escolha os recursos de API que ela pode acessar, ative e guarde o Access Token. O Magento_TwoFactorAuth não toca nesse fluxo: ele guarda a criação de token de usuário admin, não o token da integração.
Além de passar pelo 2FA, você ganha três coisas: permissão granular por recurso em vez de tudo que o usuário pode, token que não expira em 4 horas — o de admin morre com o valor de oauth/access_token_lifetime/admin, que vem 4 —, e um botão de revogar quando o fornecedor sai do projeto.
Não desligue o módulo
A busca no Google devolve, em primeiro lugar, o module:disable Magento_TwoFactorAuth. Funciona no sentido de que o erro some. Também some a única barreira entre uma senha vazada e o painel administrativo da loja.
Painel de Magento é alvo permanente de força bruta e de credencial reaproveitada de vazamento. Desligar o 2FA de uma loja em produção pra resolver um erro de integração é trocar um problema de meia hora por um risco que dura anos.
Se você desligou pra testar e esqueceu de religar, confira:
php bin/magento module:status Magento_TwoFactorAuthE, já que está aí, confira também se aquele usuário de API que você criou pra integração continua existindo com senha antiga. Ele não precisa mais existir depois que a integração passa a usar token de integração.
Perguntas rápidas
O token que sai do endpoint de 2FA é diferente do token normal?
Não. É o mesmo token de admin de sempre, com o mesmo tempo de vida e usado do mesmo jeito no cabeçalho Authorization. O que muda é só o caminho para consegui-lo, que agora exige o código do segundo fator.
Uso Duo Security. O fluxo é igual ao do Google?
O endpoint final é o /V1/tfa/provider/duo_security/authenticate, mas antes dele você chama o get-authentication-data para obter os dados da sessão do Duo. Não é um código de seis dígitos como no Google, então o corpo da requisição é diferente.
Minha loja é Adobe Commerce na nuvem. Muda alguma coisa?
Os endpoints são os mesmos, porque o módulo é o mesmo. O que muda é que em ambientes de nuvem o 2FA já vem habilitado e forçado, então você vai encontrar esse erro logo na primeira integração em vez de descobrir depois.
Pra conferir na fonte
- Magento_TwoFactorAuth etc/webapi.xml — GitHub
- Token-based authentication — Adobe Developer
- Prerequisite tasks for REST tutorials — Adobe Developer
- Integrations — Adobe Experience League