skip to content

Flows and Response Types

Which response_type a client asks for and what that decides: whether a code, an id_token or both come back, and on which channel. The answer for an SPA is not the one for a server app.

part ofFederated identityoverview, primer and where to startread it →
on this pageshow

questions

4

In OpenID Connect, what does `response_type=code` ask a provider to return to the client's redirect URI?

level: juniorimportance: must knowfreq 72%

answer

  1. one artefact on the redirect
  2. the front channel carries a placeholder
  3. identity arrives on the second leg
  4. server-to-server exchange, no browser
  5. code first, id_token from the token endpoint

basics

~20 s

A single short-lived authorization code, and nothing else. With response_type=code the provider puts no ID token and no access token on the redirect; the client exchanges the code at the token endpoint and receives both there.

solid answer

~40 s

`response_type=code` selects what the specification calls the Authorization Code Flow. The provider redirects the user agent back to the registered redirect URI carrying one short-lived authorization code and nothing else — the `id_token` and the access token are not in that response. The client then makes a direct back-channel request to the `token_endpoint`, presents the code, and receives the `id_token` and the access token in a JSON body. Because the identity artefacts are not delivered through the user agent, this is the response type the specification's own flow comparison describes as returning all tokens from the token endpoint and not revealing them to the user agent. It is what nearly every client shape asks for today.

code

http · 6 lines
http
GET /authorize?response_type=code
  &scope=openid%20profile
  &client_id=board-4711
  &redirect_uri=https%3A%2F%2Fboard.pilotage.example%2Fcb
  &nonce=n-0S6_WzA2Mj HTTP/1.1
Host: idp.pilotage.example

go deeper

for a junior

Recall the shape: one code comes back on the redirect, and the ID token and access token come from a second, separate call to the token endpoint. Being able to say which artefact is on which leg is the whole of the junior answer.

for a middle

Explain why the split exists: the redirect passes through a user agent, the token-endpoint call does not, and the code is a single-use handle rather than a credential. Name the other five response_type values and which flow each selects.

for a senior

Show that you read response_types_supported before integrating, and that you can say what response_type does not control — client authentication, claim selection and the redirect encoding are three separate decisions that candidates routinely fold into this one.

for a principal

The angle worth owning is standardising one response type across an estate: a single choice removes a class of integration review, but it forces every client shape to have somewhere to make a back-channel call from, which is a deployment cost, not a protocol one.

## The parameter and what it decides An OpenID Connect authentication request is an HTTP request to the provider's `authorization_endpoint`. It carries, among other things, a `client_id`, a redirect URI the provider has already registered against that client, the scope values being asked for (which must include `openid`, or it is a plain OAuth 2.0 authorization request rather than an OpenID Connect one), and a `response_type`. `response_type` is the single parameter that decides **which artefacts come back and on which channel they arrive**. The specification defines six values: `code`, `id_token`, `id_token token`, `code id_token`, `code token` and `code id_token token`. The value `code` is the plainest of them, and it means: *return one authorization code, and nothing more*. ## What the authorization response actually carries The provider authenticates the end user, collects whatever consent its policy requires, and then redirects the user agent back to the registered redirect URI with an authorization code attached to it. Two things are deliberately **absent** from that redirect: - the `id_token` — the signed statement about who just signed in; - the access token — the credential a resource server will accept. The code is not a credential for any API. It is a single-use, short-lived handle that means *a grant exists, come and collect it*. On its own it signs nobody in: a relying party that received the redirect and stopped there knows only that something happened at the provider. ## Where the identity artefacts come from The client then opens its **own** connection to the provider's `token_endpoint`. That leg is a direct server-to-server request; the user agent is not involved and never sees it. The client presents the code (and, if it is a confidential client, authenticates itself), and the provider answers with a JSON body carrying the access token, its `token_type` — `Bearer` — a lifetime, and the `id_token`. So the sign-in is a two-leg affair: a front-channel leg through the browser that carries only a placeholder, and a back-channel leg that carries the artefacts that matter. ## The six values and the three flows they select | `response_type` | Flow the specification names | Returned from the `authorization_endpoint` | |---|---|---| | `code` | Authorization Code Flow | an authorization code | | `id_token` | Implicit Flow | an `id_token` | | `id_token token` | Implicit Flow | an `id_token` and an access token | | `code id_token` | Hybrid Flow | a code and an `id_token` | | `code token` | Hybrid Flow | a code and an access token | | `code id_token token` | Hybrid Flow | a code, an `id_token` and an access token | A provider publishes the values it is willing to run in its `response_types_supported` metadata field, so a client can check before it asks rather than discovering it in an error. ## Why `code` is the ordinary answer The specification compares the three flows on a handful of properties, and the Authorization Code Flow is the only one that holds all of these at once: 1. **All tokens are returned from the token endpoint**, not from the authorization endpoint. 2. **Tokens are not revealed to the user agent**, because they never travel on the redirect. 3. **The client can be authenticated** on the token-endpoint leg, so a confidential client's credentials are part of the exchange. There is a cost, and it is honest to state it: the code flow takes an extra round trip, and most of its traffic is server-to-server, which means the client needs somewhere to make that call from. ## What `response_type=code` does not decide It is easy to over-read this parameter. It does **not** decide: - **how the client proves who it is** at the token endpoint — that is a separate choice, and it is why two clients with very different secret-keeping abilities can send the identical `response_type`; - **which claims come back** — the scope values asked for select the claim set; - **how fresh or how strong the sign-in must be** — separate request parameters ask for that; - **how the artefacts are encoded onto the redirect** — `response_mode` governs that, orthogonally, and a provider advertises what it supports in `response_modes_supported`. Changing `response_mode` changes the packaging, never the contents. One consequence worth carrying: because `response_type=code` returns no `id_token` from the authorization endpoint, the `nonce` request parameter is optional for it, whereas any response type that does return an `id_token` there makes `nonce` required. What a relying party then does with that claim is the ID token's own subject.

  • The redirect arrived with a code but the client never calls the token endpoint. Who is signed in?
    Nobody. An authorization code asserts nothing about an end user and carries no claims a relying party can read. It is a handle to a grant sitting at the provider, single-use and short-lived. Until the client exchanges it at the `token_endpoint` and validates the `id_token` that comes back, the relying party has no authenticated subject and must not establish a session.
  • How does a client know in advance whether a provider will accept `response_type=code`?
    It reads the provider's configuration document. The `response_types_supported` member lists every `response_type` value the provider is willing to run, and `response_modes_supported` lists the encodings it will use for the redirect. Checking these at bootstrap turns an integration failure into a startup assertion. The document itself — how it is fetched and what else it carries — is the discovery subject.
  • Does `response_type=code` alone make the request an OpenID Connect request?
    No. `response_type=code` is an OAuth 2.0 value and works perfectly well without any identity layer. What makes the request an OpenID Connect authentication request is asking for the `openid` scope value: that is what obliges the provider to return an `id_token` at all. Send `response_type=code` without it and you get an access token and no identity statement.

An authorization code is a cloakroom ticket, not the coat. It is handed over in the open and is worth nothing by itself; it becomes the coat only when the client presents it at the counter, on its own terms.

saying these in an interview costs you the question

  • Says the ID token arrives on the redirect when response_type is code.
  • Thinks an authorization code is a credential a resource server will accept.
  • Claims the token-endpoint call also travels through the user agent.
  • Believes one authorization code can be exchanged repeatedly for fresh tokens.
  • Assumes response_type=code by itself makes a request an OpenID Connect one.
open as a page

Which `response_type` should a browser-only client and a server-side client each ask for, and what differs downstream?

level: middleimportance: must knowfreq 64%

basics

~20 s

Both ask for response_type=code. The response type is the same because neither wants identity artefacts delivered through the browser; what differs is the token-endpoint leg, where the server-side client can authenticate itself and the browser-only client cannot.

open as a page

Which `response_type` delivery property matters when a sign-in lands in a browser on a screen a whole crew room can read?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Whether the response type returns identity artefacts from the authorization endpoint. Any value carrying id_token or an access token there delivers it inside the redirect URI, on a display several people can read; response_type=code leaves only a single-use handle on that channel.

open as a page

With `response_type=code id_token`, what arrives on the redirect, and what does the ID token's `c_hash` bind it to?

level: seniorimportance: should knowfreq 38%

basics

~20 s

A code and an id_token arrive together on the redirect, which is the Hybrid Flow. Because both travelled the front channel, the id_token must carry c_hash, a value derived from that code, so the client can prove the two belong to one response.

open as a page