skip to content

After a native app's OAuth 2.0 authorization request opens in the device's browser, how does the response reach the app?

level: middleimportance: must knowfreq 58%

answer

  1. three shapes, three routing mechanisms
  2. one of them is not routed at all
  3. scheme with a single slash after it
  4. a domain the platform verified for the app
  5. a listener on the loopback interface

basics

~20 s

RFC 8252 defines three redirect forms for a native client: a private-use URI scheme the operating system dispatches to the application, a claimed https URI the platform routes to it, and a loopback address the application is itself listening on.

solid answer

~40 s

The authorization server always does the same thing — it issues a redirect to the registered `redirect_uri` carrying `code` and `state`. What differs is who picks that redirect up. With a **private-use URI scheme** such as `com.example.app:/oauth2redirect/example-provider`, the browser hands the URI to the operating system, which dispatches it to whichever installed application declared that scheme; note the single slash, because a private-use scheme has no naming authority and so no authority component. With a **claimed `https` URI**, the platform has verified an association between the application and that domain and diverts the navigation to it. With a **loopback redirect** — `http://127.0.0.1:{port}/{path}` or `http://[::1]:{port}/{path}` — nothing is diverted at all: the application has opened a temporary listener and the browser simply makes an ordinary local HTTP request to it.

code

http · 8 lines
http
GET /authorize?response_type=code&client_id=s6BhdRkqt3
    &scope=parking.pay
    &state=af0ifjsldkj
    &redirect_uri=com.example.parking%3A%2Foauth2redirect%2Fcity HTTP/1.1
Host: as.example.gov

HTTP/1.1 302 Found
Location: com.example.parking:/oauth2redirect/city?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj

go deeper

for a junior

Know that the answer comes back through the browser as a redirect, and that the device — not the authorization server — is what hands it to the application.

for a middle

Be able to name all three forms, write the private-use one with a single slash, and say who performs the routing in each case.

for a senior

Show that you pick per platform and per build: which forms the devices you ship on actually support, what each one degrades to, and why a loopback listener is a poor fit on a phone.

for a principal

The angle is registering a coherent set across a client estate — several device families, one client record — and what that costs in review and in support when a platform changes its association rules.

## The problem the redirect has to solve A web client's redirection endpoint is a URL on a server it runs, so the authorization response just arrives there. A native client has no such place. Its authorization request was deliberately rendered in a browser it does not control, and the answer comes back as an HTTP redirect **in that browser**. Something on the device has to carry the response across the process boundary and into the application that started the flow. Throughout, the division of labour is fixed: the **authorization server** issues a redirect response to the registered `redirect_uri`; the **browser** follows it; the **operating system** (in two of the three forms) decides which local process the target belongs to. The authorization server never contacts the application. ## Form 1 — a private-use URI scheme The client registers a `redirect_uri` whose scheme is not `http` or `https` but a string the application has declared to the platform: ``` com.example.app:/oauth2redirect/example-provider ``` - The scheme **should be a domain name under the developer's control, written in reverse order**. That is what makes an accidental collision with another installed application unlikely. - There is **one slash**, not two. A `//` introduces an authority component, and a private-use scheme has no naming authority to put there. - Delivery is the platform's: the browser hands the URI over, the operating system looks up who declared the scheme, and that application is launched or resumed with the URI. The weakness is in that lookup. Nothing registers private-use schemes globally, so another installed application may declare the same string and become the recipient. ## Form 2 — a claimed `https` URI The client registers an ordinary-looking HTTPS URL, and the platform holds a **verified association** between that domain and the installed application, so a navigation to it is diverted to the application instead of being fetched. - The destination is the strongest of the three, because the association rests on the operating system checking something published under a domain the developer controls — another application cannot simply declare it. - The cost is that it requires the platform's association mechanism to be in place, and the URL is a real address: if no installed application has claimed it, the browser just loads the page there. - To the authorization server the registration is indistinguishable from a web client's. ## Form 3 — a loopback redirect The application opens a short-lived HTTP listener on the device's own loopback interface and registers `http://127.0.0.1:{port}/{path}` or `http://[::1]:{port}/{path}`. - Nothing is diverted: the browser makes a normal HTTP request to the local listener, which reads `code` and `state` straight off the query string. - Plain `http` is acceptable here because the request never leaves the device. - The port is taken from the operating system at run time, which is why an authorization server has to allow any port on a loopback redirect at request time. - It suits applications on a general-purpose computer far better than a phone, where running a listener is often not an option. ## Choosing between them | Form | Who routes the response | What binds it to the right app | Main exposure | |---|---|---|---| | Private-use URI scheme | operating system, by declared scheme | nothing but the scheme string | another app declaring the same scheme | | Claimed `https` URI | operating system, by verified domain association | the platform's domain check | falls back to loading the web page | | Loopback address | nobody — the browser calls the app directly | the app holding the port | another local process taking the port | A client can register more than one, and typically does when it runs on several kinds of device. What it cannot do is treat the choice as cosmetic: each form fails in a different way, and the failure is local to the device rather than on the network. ## Where the neighbouring half sits All three forms carry the authorization code across a hop the client does not fully control, so all three raise the same question: what if it lands in the wrong process? The answer is a separate mechanism — the per-request proof key of the authorization-code flow (RFC 7636) — which is what makes an intercepted `code` unusable. The redirect form decides *where the code can land*; it is not what makes a captured one worthless.

  • Why is plain http acceptable for a loopback redirect when it is not acceptable anywhere else?
    Because the request never leaves the device: the browser connects to a listener on the same host over the loopback interface, so there is no network path for anyone to observe or modify. The address is the literal `127.0.0.1` or `[::1]` precisely so that it cannot resolve somewhere else.
  • May a native client register more than one redirect form?
    Yes, and clients shipped across several kinds of device usually do — a claimed `https` URI where the platform supports the association, a private-use scheme as the fallback, and a loopback address for a desktop build. Each registered value is a separate entry; the flow uses whichever one the request named.
  • Which form would you avoid on a phone, and why?
    The loopback form. It assumes the application can open and hold a listening socket for the duration of the flow, which a mobile platform may not permit or may kill in the background. It is the natural choice on a general-purpose computer, where the application is a long-running process.

saying these in an interview costs you the question

  • Thinks the authorization server pushes the response to the application directly.
  • Says a native app can only ever use a private-use URI scheme.
  • Writes a private-use scheme redirect with two slashes after the scheme.
  • Believes the loopback form needs a routable DNS name for the device.
  • Treats the choice of redirect form as cosmetic with no security difference.