SSO Callback and Session Establishment Flow

How the receiving site verifies the token, builds a login state, and returns the user to the page they wanted

CallbackSessionCookieAuthentication flowImplementation
8 min read

Introduction

The previous article covered how the sending site issues a signed handoff token for cross-site single sign-on (SSO). This one picks up where that left off: what the site on the receiving end actually does.

Between the token arriving at the receiver's entry point and a logged-in page appearing on screen, there are three stages — verify, build a login state, and return the user to where they were heading. It looks instantaneous from the outside, but both the safety and the quality of the experience are decided almost entirely by how carefully this receiving side is built.

This article walks through what gets checked at each stage and how failures are handled. By the end, it should be clear that SSO isn't a mechanism for redoing a login.

What the Callback Receives

A Dedicated Entry Point for Tokens

Every site has a dedicated URL — a callback URL — for receiving handoff tokens. The sending site redirects the user to that URL with the token attached.

How the token arrives
Site A (sender)

Issues a token as the logged-in user moves

Redirect with the token attached
Site B's entry point

Receives the token, verifies it, then builds a login state

What the diagram shows is that the handover happens through a browser redirect (automatically sending the user on to another URL). The sites don't talk to each other directly behind the scenes — the user's browser is the courier.

That entry point is exposed on the public internet, so anyone can hit it with a token-shaped string attached. The design starts from a single assumption: never trust what arrives.

The Return Destination Comes Along Too

Alongside the token, the callback receives one more thing: which page to send the user to once the login state exists. They may have clicked the link because they wanted a specific product page on the destination site, and that intent should carry over.

Without it, every link would land on the home page and the user would have to search all over again. Removing the chore of logging in again is pointless if a different chore replaces it. Carrying the return destination is what keeps the journey continuous.

The Return Destination Gets Verified Too

The return destination is checked for having been rewritten to a malicious external URL. Redirecting to it unquestioned would mean using your own site to bounce users somewhere unknown.

The fix is straightforward: restrict the destination to paths within your own site. If an external URL turns up, it's ignored and the user goes to a predefined default page instead. A small detail, but these accumulate.

Verifying the Token That Arrives

Four Checks, in Order

Every token is verified before any login state is created. The signature, expiry, and single-use properties built into the token are confirmed here, one after another.

Verification steps at the entry point
Check the signature

Recompute the signature with the shared key and confirm the contents weren't rewritten

Check the expiry

Confirm the short window since issuance hasn't passed. Reject it if it has

Check single use

Confirm the one-time ID is unused. Reject if it's been used; on success, record it as used immediately

Check the destination

Confirm the token was issued for this site. Reject it if it was meant for another

What the diagram shows is that if even one of the four fails, nothing proceeds beyond it.

The order matters too. The signature comes first to establish that the contents can be trusted at all; only then are the expiry and destination inside those contents read. Reading the contents before checking the signature would mean acting on values that could have been rewritten. "When in doubt, reject" is the rule — with the sequence of checks pinned down as well.

What Happens When Verification Fails

Spelling out the reason on screen tells anyone probing the system how far they got. Knowing whether it failed on the signature or the expiry makes the next attempt more precise.

At the same time, the people running the site can't investigate without knowing why. So the details go into server-side logs only and never onto the screen. This is the one place where helpfulness and security pull against each other, and when in doubt we sided with security.

Building a Login State and Returning the User

The Receiver Creates a Session of Its Own

Once verification passes, the receiving site creates its own session — the record that holds the login state. Rather than borrowing the sender's session, it assembles a fresh login state on its own side from the user identifier carried in the token.

From that point on, the session behaves exactly like a normal login within that site. Because the product and member data behind all the sites is shared, the points balance and member pricing appear as they should. To the user, it's indistinguishable from having logged in there in the first place.

The Token's Job Ends Here

The moment the session exists, the token has done its work. It's recorded as used and will never pass verification again.

Because it's discarded after a single use, a copy sitting in history or logs afterwards can't be turned back into a login. Not creating anything long-lived is a principle that runs through the receiving side as well.

Redirect to the Original Destination

With the session in place, the user is delivered to the return destination captured at the start. Only here does the experience come together: click a link, and the page you wanted opens, already logged in.

Behind that, verification, session creation, and a redirect all run in sequence — yet it feels like a single step. It's an unusual kind of feature, where going unnoticed is exactly what success looks like.

The Receiving Side on One Page

What the table shows is that the receiving side's work reduces to four stages: receive, doubt, create, return. Those stages are identical on every site, so the shape of the processing doesn't change as sites are added.

Summary

The receiving side's job was to doubt the token that arrives, build its own login state if the token holds up, and return the user to where they were going. To recap:

  1. Trust nothing by default: a publicly reachable entry point starts with verification
  2. Four checks, in a fixed order: confirm the signature, then read expiry, single use, and destination
  3. Rebuild the session: cookies can't cross domains, so it's issued on the receiver's own domain
  4. Verify the return destination: restrict it to your own site so it can't be used to bounce users away
  5. Fail gently: drop SSO, guide the user to a normal login, and keep the reason off the screen

The failure branches add up faster than you'd expect — expired, signature mismatch, already used, wrong destination, invalid return destination, each needing defined behaviour. Working through that list was where an AI agent helped, enumerating "what happens if a request arrives like this?" until the gaps were closed.

The token design itself is in "How Signed Handoff Tokens Work", and where SSO fits overall is in "Single Sign-On Across Multiple EC Sites". Managing entry-point URLs and the permitted-site list is covered in "SSO Configuration That Scales with New Sites".