OAuth Device Flow no Node.js permite autenticar dispositivos que não possuem navegador conveniente ou teclado completo, como TVs, consoles, CLIs e equipamentos industriais. O dispositivo exibe um código e o usuário conclui a autorização em outro aparelho.
O fluxo é definido pelo OAuth 2.0 Device Authorization Grant. Ele não deve ser usado em aplicações web comuns, onde Authorization Code com PKCE oferece experiência e segurança melhores.
Como funciona
- o dispositivo solicita um device code;
- o servidor retorna
device_code,user_codee URL; - o dispositivo mostra instruções;
- o usuário abre a URL em outro aparelho;
- o dispositivo consulta o token endpoint periodicamente;
- após aprovação, recebe tokens.
Solicitando o device code
const body = new URLSearchParams({
client_id: process.env.OAUTH_CLIENT_ID,
scope: 'openid profile devices.read'
});
const response = await fetch(deviceAuthorizationEndpoint, {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body,
signal: AbortSignal.timeout(5000)
});
const authorization = await response.json();Resposta típica
{
"device_code": "...",
"user_code": "BCDF-GHJK",
"verification_uri": "https://id.example/device",
"verification_uri_complete": "https://id.example/device?user_code=BCDF-GHJK",
"expires_in": 600,
"interval": 5
}O device_code é secreto e não deve ser exibido. O user_code é curto e feito para digitação.
Exibindo instruções
console.log(`Acesse ${authorization.verification_uri}`);
console.log(`Digite o código ${authorization.user_code}`);Quando disponível, ofereça QR Code baseado em verification_uri_complete, mas continue exibindo o código para acessibilidade e fallback.
Polling do token endpoint
const tokenBody = new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
device_code: authorization.device_code,
client_id: clientId
});Respeite o intervalo fornecido. Polling agressivo pode ser bloqueado.
Respostas de espera
O token endpoint pode retornar:
authorization_pending: continue aguardando;slow_down: aumente o intervalo;access_denied: usuário recusou;expired_token: reinicie o fluxo.
if (error === 'slow_down') {
intervalMs += 5000;
}Loop com deadline
const expiresAt = Date.now() + authorization.expires_in * 1000;
while (Date.now() < expiresAt) {
await sleep(intervalMs);
const result = await pollToken();
if (result.access_token) return result;
if (result.error === 'access_denied') throw new Error('Autorização negada');
if (result.error === 'slow_down') intervalMs += 5000;
}Use cancelamento para que o usuário consiga interromper a espera.
Clientes públicos
Dispositivos e CLIs normalmente não conseguem proteger um client secret. Não trate um secret embutido no software como confidencial. O provedor deve registrar o cliente como público.
Escopos mínimos
Solicite apenas o necessário. Exiba ao usuário o nome do aplicativo, dispositivo e permissões antes da aprovação.
Binding ao dispositivo
O provedor deve vincular user_code ao device_code e invalidar ambos após uso. O código curto precisa ter entropia suficiente e limite de tentativas.
Phishing
O dispositivo não deve pedir senha. Ele direciona o usuário ao domínio oficial do provedor. Mostre a URL completa e evite encurtadores desconhecidos.
Remote phishing
Um atacante pode iniciar fluxo em seu dispositivo e convencer outra pessoa a digitar o código. O provedor deve mostrar detalhes claros do cliente e do dispositivo na tela de aprovação.
ID Token
Se o escopo contém openid, valide o ID Token com issuer, audience, assinatura e expiração. Consulte OpenID Connect no Node.js.
Armazenamento de tokens
Em CLI, use keychain do sistema quando possível. Em dispositivo, use armazenamento protegido. Não grave tokens em logs, arquivos world-readable ou histórico do terminal.
Refresh token
Alguns provedores retornam refresh token para sessões longas. Proteja, faça rotação e permita revogação remota. Em dispositivo compartilhado, ofereça logout explícito.
Identidade do dispositivo
O Device Flow autentica o usuário, não prova sozinho a integridade do dispositivo. Para equipamentos gerenciados, combine com mTLS, attestation ou cadastro prévio.
Rate limiting
Limite solicitações de device code, tentativas de user code e polling. Aplique limites por cliente, IP e dispositivo, evitando bloquear usuários legítimos atrás de NAT.
Observabilidade
Monitore:
- fluxos iniciados;
- aprovações e recusas;
- expirações;
slow_down;- tempo até aprovação;
- tentativas de códigos inválidos;
- tokens renovados e revogados.
Não registre device code, user code ou tokens.
Experiência de CLI
Mostre progresso sem imprimir a cada polling. Permita Ctrl+C e limpe timers. Quando possível, abra o navegador automaticamente, mantendo instrução manual.
Testes
- autorização pendente seguida de sucesso;
- slow_down;
- recusa;
- expiração;
- cancelamento local;
- resposta inválida;
- token com issuer incorreto;
- armazenamento seguro;
- rate limiting;
- reutilização de código.
Erros comuns
- usar Device Flow em aplicação web comum;
- polling abaixo do intervalo;
- exibir device code secreto;
- embutir client secret;
- não limitar tentativas;
- armazenar token em texto puro;
- não oferecer cancelamento;
- não mostrar domínio oficial;
- confundir usuário autenticado com dispositivo confiável.
Conclusão
OAuth Device Flow no Node.js oferece autenticação segura para dispositivos com entrada limitada. A aplicação inicia o fluxo, exibe um código e respeita polling e expiração definidos pelo provedor.
Trate o cliente como público, proteja tokens e solicite escopos mínimos. Para dispositivos gerenciados, combine identidade do usuário com uma identidade técnica do equipamento.
Consulte a RFC 8628 sobre Device Authorization Grant e o guia OAuth Device Flow.




