Fluxo de dispositivo
Faça o login em TVs, CLIs e outros aparelhos sem um navegador utilizável: mostre um código curto, deixe a pessoa aprová-lo em outra tela e consulte os tokens (RFC 8628).
O device authorization grant (RFC 8628) é para aparelhos que não conseguem mostrar uma tela de login, ou em que digitar uma senha seria penoso: uma smart TV, uma ferramenta de linha de comando, um quiosque. O aparelho pede ao Authio um par de códigos, mostra o curto para a pessoa e consulta o endpoint de token enquanto ela aprova o pedido no celular ou no computador.
Como funciona
O aparelho pede os códigos
Ele chama o endpoint de autorização de dispositivo e recebe um
device_code, que guarda para si, umuser_codepara a pessoa e o endereço onde o código é digitado.Ele mostra o código
Na tela: o endereço e o código e, muitas vezes, um QR code do endereço com o código já preenchido.
A pessoa aprova em outra tela
A página de verificação hospedada do realm confere o código, faz o login da pessoa se precisar e pede que ela aprove ou negue. Ela usa a marca do client que fez o pedido.
O aparelho consulta os tokens
Enquanto isso, o aparelho chama o endpoint de token a cada poucos segundos até receber os tokens, uma recusa ou o código expirar.
Configure o client
Em Clients, habilite o grant de device code (urn:ietf:params:oauth:grant-type:device_code) no client que o aparelho usa e libere os escopos que ele vai pedir — openid para um ID token, offline_access para um refresh token. Um aparelho distribuído a clientes não consegue guardar segredo, então use um client público; um client confidencial autentica as duas chamadas normalmente.
Peça um device code
curl -X POST https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/device/auth \
-d client_id=acme-tv \
-d 'scope=openid profile offline_access'| Campo | O que é |
|---|---|
device_code | A referência secreta do aparelho para o pedido. Nunca mostre. |
user_code | Oito caracteres em dois grupos, de um alfabeto sem caracteres parecidos. Maiúsculas e separadores são relevados na digitação. |
verification_uri | A página de verificação hospedada, {issuer}/device. |
verification_uri_complete | A mesma página com o código preenchido; o endereço para pôr num QR code. |
expires_in | Segundos até os códigos expirarem: 10 minutos. |
interval | O mínimo de segundos entre duas consultas: 5. |
Se o client não tiver o grant de device code, o pedido é recusado antes de qualquer código ser criado. Escopos que o client não libera também são recusados.
Mostre o código
Mostre verification_uri e user_code em letras grandes, e verification_uri_complete como QR code para celulares. A página hospedada conduz a pessoa por três passos numa tela só: informar o código (já preenchido quando vem do QR code), entrar e, por fim, aprovar ou negar.
- O login nessa página é por usuário e senha. Uma conta que exige segundo fator não consegue concluir o login ali; quem tem o app do Authio pareado pode aprovar o pedido pelo app.
- Um código desconhecido, expirado, já usado ou de outro realm é recusado.
- Aprovar abre uma sessão para o client, e os tokens do aparelho pertencem a ela: encerrar essa sessão — pelo portal da conta, pelo console ou por um logout — desconecta o aparelho.
Consulte os tokens
Espere interval segundos e chame o endpoint de token com o device code. Repita até a resposta deixar de ser authorization_pending.
curl -X POST https://authio.api.hyperio.tech/realms/acme/protocol/openid-connect/token \
-d grant_type=urn:ietf:params:oauth:grant-type:device_code \
-d device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS \
-d client_id=acme-tvEnquanto a pessoa não decide, o endpoint responde 400 com um error do RFC 8628. Quando ela aprova, ele responde 200 com a mesma resposta de tokens do fluxo de código de autorização: um access token, um ID token com openid e um refresh token com offline_access.
| Erro | Significado | O que o aparelho faz |
|---|---|---|
authorization_pending | A pessoa ainda não decidiu. | Espera interval segundos e consulta de novo. |
slow_down | O aparelho consultou antes do que interval permite. | Soma 5 segundos ao intervalo para todas as consultas seguintes e consulta de novo. |
expired_token | Os 10 minutos passaram sem aprovação. | Para e recomeça com um device code novo. |
access_denied | A pessoa negou, o código já foi resgatado ou pertence a outro client. | Para. Ofereça recomeçar. |
Consultar não estende a vida do código, e um código gera tokens uma única vez. Um laço que segue essas regras:
const issuer = 'https://authio.api.hyperio.tech/realms/acme'
const clientId = 'acme-cli'
export async function signInOnDevice() {
const authorization = await fetch(`${issuer}/protocol/openid-connect/device/auth`, {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ client_id: clientId, scope: 'openid offline_access' }),
}).then((response) => response.json())
console.log(`Abra ${authorization.verification_uri} e digite ${authorization.user_code}`)
let interval = authorization.interval * 1000
while (true) {
await new Promise((resolve) => setTimeout(resolve, interval))
const response = await fetch(`${issuer}/protocol/openid-connect/token`, {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
device_code: authorization.device_code,
client_id: clientId,
}),
})
const body = await response.json()
if (response.ok) return body
if (body.error === 'authorization_pending') continue
if (body.error === 'slow_down') {
interval += 5000
continue
}
throw new Error(body.error_description ?? body.error)
}
}No .NET, o PollDeviceTokenAsync do Authio.Client espera o intervalo antes de cada consulta, soma 5 segundos num slow_down e lança AuthioProtocolException em access_denied ou expired_token. Registre o client com AddAuthioClient e ClientAuthentication em None para um client público.
Mantenha o aparelho conectado
Guarde o refresh token no aparelho e renove o access token com o grant refresh_token, como descrito em Qualquer client OIDC. Refresh tokens são rotacionados, então guarde o novo a cada vez. Quando uma renovação falhar com invalid_grant — a sessão foi encerrada, o refresh token expirou —, comece o fluxo de dispositivo de novo.
Solução de problemas
| O que aparece | Por quê | O que fazer |
|---|---|---|
unauthorized_client ao pedir um código | O grant de device code não está habilitado no client. | Habilite-o nos grants do client. |
invalid_client | Um client confidencial não mandou o segredo, mandou o errado ou usou um método diferente do registrado. | Mande o segredo como está registrado, ou torne o client público. |
| A página diz que o login da conta não é suportado | A conta exige um segundo fator, que a página de dispositivo não oferece. | Aprove pelo app do Authio, ou use uma conta sem segundo fator obrigatório. |
access_denied logo depois de aprovar | O código foi consultado por um client diferente do que o pediu. | Consulte com o mesmo client_id que pediu o código. |