This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 1, 2026. Spotted a mistake? Tell us.
Some devices have no usable browser: a TV, a set-top box, a CLI on a remote server, a kiosk. They still need to sign a user in, and OAuth's normal redirect flow assumes a browser and a redirect URI.
The OAuth 2.0 Device Authorization Grant (RFC 8628) solves this by splitting the flow in two: the device gets a short code, the user types it on a page in a browser they already have, and the device polls for the result.
The flow
- The device requests a code. It calls the device authorization endpoint with its client ID and scopes. The response contains:
device_code— a long secret the device keeps.user_code— a short code the user will type.verification_uri— the page the user opens.expires_inandinterval.
- The device shows the user code and URL. For example: "Go to example.com/device and enter ABCD-EFGH."
- The user signs in on another device. Phone or laptop: opens the URL, types the code, approves the device.
- The device polls the token endpoint with
grant_type=urn:ietf:params:oauth:grant-type:device_codeand its device code. - The token endpoint answers with either an access token or an error:
authorization_pending(keep waiting),slow_down(increase the interval),access_denied, orexpired_token.
The device never sees the user's password, and the user never types credentials into the device.
What the specification requires
- Polling interval. The device waits
intervalseconds between polls; the server can returnslow_downto make it wait longer. - Short lifetimes. User codes expire; the device stops polling after
expires_in. - Rate limiting. The server must rate-limit the verification page, because short user codes can be guessed.
- Code handling. The device code is a secret; the user code is not, but it must be single-use.
These details are where implementations fail: a device that ignores slow_down hammers the token endpoint, and a server without rate limits turns the user code into a brute-force target.
Device flow vs loopback redirect
For CLI tools on a machine with a browser, there is another option: loopback redirect (RFC 8252). The CLI starts a local HTTP server, opens the system browser to the authorization endpoint with redirect_uri=http://127.0.0.1:port/callback, and captures the code when the browser redirects back.
| Device flow | Loopback redirect | |
|---|---|---|
| Needs a browser on the device | No | Yes |
| Needs a local HTTP listener | No | Yes |
| Works over SSH / headless | Yes | Only with port forwarding |
| UX | Type a code on another device | Just click approve |
| Best for | TVs, CLI over SSH, IoT | Desktop CLI, local tools |
Many CLIs implement both and choose at runtime.
Security notes
- Bind the user code to the client. A user code approved for one application must not mint a token for another.
- Show what is being approved. The verification page should display the application name and requested scopes; otherwise users approve blindly.
- Do not let the device poll forever. Enforce expiry and a maximum poll count.
- Treat the device code as a credential. Log it never; store it in memory only.
- Use PKCE where the client is public. The device is a public client; PKCE still helps if the authorization request supports it.
How Casdoor implements it
Casdoor supports the device authorization grant for applications that enable the Device login sign-in method:
- The device starts at
/api/device-authwith itsclient_idandscope, and receives a device code, a user code, a verification URI and an expiry. - The user approves the code in the browser; the approval can be cancelled through the matching cancel endpoint.
- The device exchanges the device code at the token endpoint with the standard
urn:ietf:params:oauth:grant-type:device_codegrant type.
That makes the same identity provider usable for browser apps, mobile apps and CLIs without a second authentication system.
When to use it
Use the device flow when the device cannot run a browser or cannot receive a redirect. Use the authorization code flow with PKCE for everything that can. And if you are building a CLI that runs on a developer's laptop, prefer loopback redirect with device flow as the fallback.
Related reading: OAuth vs OIDC, OAuth vs SAML and authorization for AI agents.
Sources
- RFC 8628: OAuth 2.0 Device Authorization Grant
- RFC 8252: OAuth 2.0 for Native Apps
- RFC 6749: The OAuth 2.0 Authorization Framework
Product names are trademarks of their respective owners.