Federated login and passkeys

Use authorization code with PKCE

Start a modern authorization flow with state and PKCE, validate the callback, and exchange a one-time code without exposing tokens in URLs.

8 minute lesson

~~~

The authorization code flow sends the browser back with a short-lived code. PKCE binds that code to the client instance that began the flow.

Generate a secure state value and PKCE verifier, store them in a short-lived transaction, send the derived challenge, and validate state exactly on callback. Use exact registered redirect URIs and exchange the code server-side where the application architecture supports it.

The browser-visible request contains the challenge, not the verifier:

verifier → SHA-256 → base64url challenge

After the callback, the client sends the original verifier to the token endpoint. A party that steals only the authorization code cannot complete the exchange without it.

state and PKCE protect different links. state ties the callback to the browser transaction and helps prevent login CSRF. PKCE ties the code to the client that started the flow. Use both according to the provider and library guidance.

Store the transaction server-side or in a protected, short-lived mechanism. Bind it to the authorization server that was selected, and include the intended post-login destination after validating it as a safe local path. A client that supports several issuers must validate the callback issuer, or use distinct redirect URIs, so a response from one provider cannot be confused with a transaction started at another. Never accept an arbitrary callback returnTo URL and redirect to it.

Consume the transaction once. A second callback with the same state, code, or verifier should fail even inside the expiry window.

Implement a fake provider flow in tests. Cover wrong state, wrong verifier, wrong issuer, reused code, expired transaction, and an external return URL.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →