skip to content

Why does an OAuth 2.0 client send the user to the authorization server to log in and then back?

level: juniorimportance: must knowfreq 75%

answer

  1. delegation, not a shared password
  2. the password never reaches the application
  3. browser out, direct call back
  4. a code is not a token
  5. response_type=code, then grant_type=authorization_code

basics

~20 s

The authorization code grant keeps the resource owner's password at the authorization server. The user authenticates there, and the client receives only a short-lived authorization code, which it exchanges on a back channel for a scoped access token.

solid answer

~40 s

That round trip is the **authorization code grant**, and it exists so the client never handles the resource owner's password. The client sends the browser to the authorization server's authorization endpoint with `response_type=code`, its `client_id`, a `redirect_uri` and the `scope` it wants. The resource owner authenticates and approves at the authorization server, which redirects the browser back to the client carrying a short-lived authorization code. The client then posts that code to the token endpoint as `grant_type=authorization_code` over a direct server-to-server call and gets back an `access_token` with `token_type` and `expires_in`. Two legs, two channels: the browser carries the request out and the code back; the token never travels through the browser at all.

code

http · 9 lines
http
GET /authorize?response_type=code
  &client_id=s6BhdRkqt3
  &redirect_uri=https%3A%2F%2Forders.nursery.example%2Fcb
  &scope=orders.write
  &state=af0ifjsldkj HTTP/1.1
Host: as.catalogue.example

HTTP/1.1 302 Found
Location: https://orders.nursery.example/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj

go deeper

for a junior

Recall the shape: the user logs in at the other site, the application gets a code, and the code is swapped for a token behind the scenes. The password never reaches the application.

for a middle

Explain the two legs and why they use different channels: the browser carries a code that is useless on its own, and the token arrives on a direct call the browser never sees.

for a senior

Show the consequences you have lived with: a client compromise does not expose account passwords, withdrawal of access is one record at the authorization server, and the token is bounded in scope and time.

for a principal

Frame the redirect as a boundary decision — which party is allowed to hold a credential to the whole account, and what it costs an estate when that boundary is crossed for convenience.

## What a grant is, and why the redirect is one OAuth 2.0 calls the resource owner's permission an **authorization grant**. `grant_type` is the value the client sends to the **token endpoint** naming which flow produced that permission. The redirect-based one is `authorization_code`, and it is the grant behind almost every "connect your account" button. The design it replaces is the obvious one: ask the buyer for their wholesale catalogue password and log in as them. That is precisely what the framework exists to avoid. A password is a credential to the *whole* account, for an unbounded time, at every interface the account has. A delegated grant is a credential to *one slice* of the account, for a bounded time, issued to *one named client*. ## The two legs 1. **Front channel (through the browser).** The garden centre's ordering integration sends the buyer's browser to the authorization server's authorization endpoint with `response_type=code`, its `client_id`, its registered `redirect_uri`, the `scope` it is asking for, and a `state` value it will check when the browser comes back. The buyer authenticates *at the authorization server* and approves. 2. **Back channel (server to server).** The authorization server redirects the browser to the client's redirection endpoint with a short-lived authorization code in the query string. The client then makes a direct HTTP request to the token endpoint with `grant_type=authorization_code` and that code, and receives a token response containing `access_token`, `token_type` and `expires_in`. | Leg | Carried by | Carries | Who can read it | |---|---|---|---| | Authorization request | The browser, as a redirect | `response_type=code`, `client_id`, `redirect_uri`, `scope` | The user, and anything with sight of the browser | | Authorization response | The browser, as a redirect back | A short-lived authorization code | The user, and anything with sight of the browser | | Token request and response | A direct call from the client | `grant_type=authorization_code`, then the access token | Only the client and the authorization server | The split is the whole point. The visible, tamperable leg carries something that is **not usable on its own**; the usable thing is fetched over a leg the browser never sees. ## What the redirect actually buys - **The password stays where it was set.** The client's code, logs, memory and support desk never contain it, so a compromise of the client is not a compromise of the account's password. - **The authorization server keeps control of the authentication ceremony.** Whatever it does beyond checking a password — a second factor, a step-up, a risk decision — still happens, because the user is standing in front of it. - **The resource owner sees who is asking.** Approval happens on the authorization server's own pages, for a named `client_id` and a named `scope`. - **What the client gets is bounded.** An `access_token` carries a scope and an `expires_in`; a password carries neither. - **Withdrawal is one record.** Ending the client's access is a decision at the authorization server, not a password change that breaks everything else the buyer uses. ## What the client never learns It never learns the resource owner's password, and it never learns anything the authorization server did not put in the token response or in the token itself. An access token obtained this way says *what the client may do*; it is not, on its own, a statement about who is at the keyboard — a separate identity layer exists for that question. ## When the redirect is the wrong shape The redirect assumes two things: a resource owner is **present**, and the client can **get a browser in front of them**. Remove either assumption and this grant stops applying: - A nightly stock-and-price synchronisation runs at 03:00 with nobody to redirect. There is no resource owner delegating anything; the client acts for itself, which is the `client_credentials` grant. - A device with no usable browser or keyboard cannot render an authorization page at all. OAuth 2.0 defines a separate grant for input-constrained devices, which moves the approval onto a second device the user already holds. So the answer to "why the redirect?" is not "because that is how the library works". It is: the only party entitled to see the resource owner's password is the authorization server, so the flow is arranged to put the user in front of it — and the code that comes back is deliberately worthless until the client redeems it somewhere the browser cannot reach.

  • Which part of this exchange travels through the browser, and which does not?
    The authorization request and the authorization response both travel through the browser as redirects, so the user and anything watching the browser can see them. The code exchange does not: the client posts `grant_type=authorization_code` to the token endpoint on its own connection, and the access token comes back on that same direct connection.
  • What does the client send to the token endpoint, and what comes back?
    A form-encoded POST carrying `grant_type=authorization_code`, the code, and the same `redirect_uri` that was used on the authorization request. The response is JSON with `access_token`, `token_type` and `expires_in`, and it may include a refresh token so the client can carry on once the resource owner has gone.
  • Does completing this grant tell the client anything about which human approved it?
    Not by itself. The grant produces an access token that says what the client may do at a resource server. Establishing who authenticated is a separate identity layer built on top of these grants, with its own token and its own rules.

A contractor signs a visitor in at the building's own reception; reception hands the contractor a numbered slip, which the security desk swaps for a pass that opens one floor until six o'clock. The contractor never learns the visitor's door code.

saying these in an interview costs you the question

  • Says the client collects the user's password and forwards it
  • Calls the authorization code an access token
  • Thinks the code is exchanged through the browser
  • Says the code can be redeemed repeatedly for more tokens
  • Assumes every OAuth 2.0 grant involves a redirect