Tuesday, May 26, 2026Tech HubAboutContactAdvertiseNewsletter
Back to Home
OAuth 2.0 – Device flow explained for Engineers, especially for Backend Engineers

OAuth 2.0 – Device flow explained for Engineers, especially for Backend Engineers

B
Blizine Admin
·1 min read·0 views

OAuth 2.0 – Device flow explained for Engineers, especially for Backend Engineers - Stack Overflow

Stack Overflow Business Stack Internal: the knowledge intelligence layer that powers enterprise AI.Stack Data Licensing: decades of verified, technical knowledge to boost AI performance and trust.Stack Ads: engage developers where it matters — in their daily workflow.First time I tried to login to Netflix at a hotel TV I almost gave up. The remote was having only four arrow keys and a number pad. My password was 18 characters with symbols. Whoever designed the login screen had either never used it themselves, or they had decided suEering builds character.After few years, the same TV’s started doing something different. They showed us a short code and an URL. I opened phone, typed the URL, entered the code and we are in. No remote-control circus. No password on a TV.That is OAuth 2.0 device authorization grant. Most of the people just call it that device flow.If we run aws sso login, gh auth login, or signed into Spotify on an Xbox, we have already used it. And if you are build a backend for a CLI, an IOT device, a smart TV app or anything where typing a password is really painful or not safe, we should end up implementing it sooner or later.Here is the step by stepStep1: Assume we are building a CLI called mycli. The user runs:$ mycli loginBelow will happen behind the scenes.Step 1: The CLI asks for a codeThe CLI sends a POST to authorization server:POST /oauth/device_authorization HTTP/1.1 Host: auth.example.com Content-Type: application/x-www-form-urlencoded client_id=mycli-prod&scope=read:repos%20write:reposThe server responds with something like this:{ "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS", "user_code": "WDJB-MJHT", "verification_uri": "https://example.com/device",

"verification_uri_complete": "https://example.com/device?user_code=WDJB- MJHT",

"expires_in": 1800, "interval": 5

}Five fields actually matter:• device_code is a long, opaque string. The CLI keeps this private.• user_code is the short, human-friendly one. The CLI shows this on screen. • verification_uri is where the user goes to enter the code.• expires_in is how long the exchange is valid. Usually 15 to 30 minutes. • interval is how often the CLI is allowed to poll for the token. We will get to that.Step 2: the CLI tells the user what to doYour CLI prints something like:Open this URL in your browser: https://example.com/device

Enter this code: WDJB-MJHT Waiting for confirmation...The user goes to their phone or laptop, opens the URL enter the code and signs in normally with SSO and approves the request.Step 3: CLI polls the token endpointWhen we are using phone, the CLI is in the loop and every five seconds it try to reach the server and get the statusPOST /oauth/token HTTP/1.1 Host: auth.example.com Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:device_code &device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS &client_id=mycli-prodThe server’s response is one of the five things, this is the part most of us will get wrong on the first implementation.Five response we should handleAuthorization_pending – Users not approved yetslow_down – you are polling too fast. The RFC says you must increase your interval by at least 5 secondsexpired_token – Exchange ran out of time, stop pollingaccess_denied – User clicked no or closed the page. Stop pollingsuccess – the token is in the body, like a normal OAuth response:{ "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "v1.MRn7...", "scope": "read:repos write:repos" }That is the whole protocol. If we can handle those five cases, we will have a working device flow client.Few additional things to take care of1. Treating user_code like it is secret. It is not. The user types it into their phone. Your job is to make it short enough to read but unguessable. The standard is 8 to 9 alphanumeric characters with the confusing ones removed (no 0, O, I, 1). GitHub uses 8 characters in the format XXXX XXXX. That is a good template.2. No rate limiting on the verification page. The endpoint where users enter the user_code is a brute-force target. With a 9-character code from a reduced alphabet, you have plenty of theoretical entropy, but pending codes at any given moment number in the thousands. Lock it down. Per-IP, per-session, exponential backoff after failures.3. Ignoring slow_down. I have seen clients that sleep for the same interval forever, no matter what the server says. That works in dev. In production it gets you flagged as abusive.4. Not expiring the user_code immediately on use. Once the user submits the code, mark it consumed. Atomically. If your check-then-mark logic is not transactional, you have a real bug waiting to happen.5. Confusing this with PKCE. Device flow is for input-constrained devices. PKCE is for public clients (mobile apps, SPAs) that cannot keep a secret. They look similar on the surface (no client secret) but solve different problems. You sometimes need both. Device flow + PKCE is fine and increasingly common.ConclusionThe device flow is one of those protocols that looks complicated in the RFC but actually fits on a napkin. Two endpoints, five response cases, Once you have built it once, you will wonder why anyone ever bothered with passwords on TVs.If you are shipping a CLI today and still asking users to paste personal access tokens into a prompt, do them a favor. Spend an afternoon implementing this. Your users will notice.These articles are licensed under a Creative Commons Attribution-ShareAlike 4.0 International license. creativecommons.org/licenses/by-sa/4.0/deed.en AuthorsSrikanth SrinivasSrikanth Srinivas is a Software Engineering leader with over 21 years of experience building scalable enterprise applications, cloud-native platforms, and automation-driven engineering solutions across web, mobile, API, and DevOps ecosystems. He has led technology initiatives…The HeapauthCC BY-SA 4.0 Recent articles May 22, 2026Dispatches from O'Reilly: The accidental orchestrator May 21, 2026Coding agents are giving everyone decision fatigue May 18, 2026Interviews Aren’t About You (Sorry) May 15, 2026No Dumb Questions: What is cloud computing and why is everyone doing it? Latest Podcast May 26, 2026Do you have what it takes to run AI in production?Add to the discussionLogin with your stackoverflow.com account to take part in the discussion.

📰Originally published at stackoverflow.blog

Comments