Proposal: Add Steam (OpenID 2.0) as an official Auth.js provider #13431
Replies: 3 comments
-
|
Yes, if this could be done then it would be a huge help to the NextAuth Community. |
Beta Was this translation helpful? Give feedback.
-
|
This is a solid and well-reasoned proposal. Adding Steam as a built-in provider clearly addresses a real demand, and the approach of implementing OpenID 2.0 using only the Web-standard fetch API is a strong design choice for cross-runtime compatibility. The introduction of the token.request hook feels like a clean and extensible solution, especially since it keeps the existing OAuth flow untouched while enabling support for non-OAuth providers. The minimal and backward-compatible change to the callback handler is also a big plus. Regarding the design questions: using [email protected] as a synthesized email is reasonable as long as it’s clearly documented, and exposing token.request as a supported (advanced) API would likely benefit future integrations. Overall, this looks like a practical and well-implemented contribution. |
Beta Was this translation helpful? Give feedback.
-
|
This is a solid proposal that elegantly bridges the gap between modern Edge-compatible architecture and legacy OpenID 2.0. By implementing the token.request hook, you’re providing a clean "escape hatch" that solves the Steam issue while future-proofing the core for other non-standard protocols. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Goals
Non-Goals
Background
Steam is one of the most requested auth providers in the Auth.js ecosystem. It has over 35 million daily active users and is the dominant identity system in PC gaming. Developers building gaming dashboards, tournament platforms, and community sites routinely need Steam login.
Why Steam is not already supported:
Steam uses OpenID 2.0 — a protocol older than and fundamentally incompatible with OAuth 2.0. Every built-in Auth.js provider (Google, GitHub, Discord, etc.) uses OAuth 2.0 or OIDC. OpenID 2.0 has no authorization code — Steam redirects the user back to your callback URL with a signed assertion in the query string, which must then be verified by re-posting those params to Steam's endpoint with openid.mode=check_authentication.
Current alternatives:
The core blocker:
Auth.js v5's handleOAuth callback handler has no hook to bypass the oauth4webapi authorization-code grant flow. Without a token.request escape hatch, it is impossible to implement a non-OAuth-2.0 provider cleanly from the outside.
I have a working implementation that solves all of these issues, which I am proposing to contribute.
Proposal
I have a complete working implementation ready to submit as a PR. It consists of two changes:
1. packages/core/src/providers/steam.ts (new file)
A fully typed Steam provider following the exact same structure as all other built-in providers. Key implementation details:
2. packages/core/src/lib/actions/callback/oauth/callback.ts (small modification)
A single new if-branch added before the oauth4webapi code-grant call:
if (provider.token?.request) {
// call token.request with the OpenID callback params
// then call userinfo.request with the resulting tokens
// return early — skip the entire oauth4webapi flow
}
// existing code continues unchanged for all OAuth 2.0 providers
This is fully backward-compatible. Every existing provider that does not set token.request falls through to the existing code path unchanged.
Tests:
13 unit tests covering config shape, authorization URL construction, profile mapping, token.request (valid assertion, is_valid:false, wrong endpoint, bad claimed_id), and userinfo.request (success, missing token, empty player list). All tests pass.
I am interested in contributing and have the PR ready to open once the discussion confirms the maintainers are open to this approach.
The main design question I would appreciate guidance on:
Beta Was this translation helpful? Give feedback.
All reactions