What is the `state` parameter in OAuth?

`state` is a random, per-request value that binds an OAuth flow to the user's session — the defense against CSRF on the callback.

· LoginWith team

state is a parameter in the OAuth 2.0 authorization request. The client generates a random value, sends it with the request, and verifies it on the callback. It’s the defense against CSRF attacks on OAuth flows.

The attack it prevents

Without state, an attacker can:

  1. Start their own OAuth flow and receive a callback URL with an authorization code
  2. Send that callback URL to the victim (via a link, an iframe, etc.)
  3. The victim’s browser hits the callback, and now the victim’s session is bound to the attacker’s account

With state, step 3 fails — the victim’s session doesn’t have the matching state, so the callback is rejected.

How to use it

On the authorize redirect:

1. Generate a random value (32+ bytes): state = randomBytes(32)
2. Store it in the user's session (cookie): session.oauth_state = state
3. Include it in the authorize URL: ?state=<value>

On the callback:

1. Read state from the query: req.query.state
2. Read the stored value: session.oauth_state
3. Compare. If different, reject.

Gotchas

  • Always use a cryptographically random value. Don’t reuse.
  • Store it somewhere that survives the redirect — a cookie, usually. Not in-memory.
  • Clear it after use, so replay attacks don’t succeed.

See the full auth glossary for related terms.

Want auth that just works?

Get started with LoginWith