Implement "Sign In with OpenRouter" using OAuth PKCE — framework-agnostic, no SDK or client registration required. Use when the user wants to add OpenRouter login, authentication, sign-in buttons, OAuth, or AI model inference API keys for browser-based apps. No client registration, no backend, no secrets required.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Implement "Sign In with OpenRouter" using OAuth PKCE — framework-agnostic, no SDK or client registration required. Use when the user wants to add OpenRouter login, authentication, sign-in buttons, OAuth, or AI model inference API keys for browser-based apps. No client registration, no backend, no secrets required.
version
2.0.0
compatibility
browser (requires Web Crypto API, localStorage, sessionStorage)
Sign In with OpenRouter
Add OAuth login to any web app. Users authorize on OpenRouter and your app receives an API key — no client registration, no backend, no secrets. Works with any framework.
Just implement the PKCE flow — skip the button section
Use the OpenRouter SDK after auth
Do PKCE here for the key, then see openrouter-typescript-sdk skill for callModel/streaming
OAuth PKCE Flow
No client ID or secret — the PKCE challenge is the only proof of identity.
Step 1: Generate verifier and challenge
code_verifier = base64url(32 random bytes)
code_challenge = base64url(SHA-256(code_verifier))
Use crypto.getRandomValues(new Uint8Array(32)) for the random bytes
base64url encoding: standard base64, then replace + → -, / → _, strip trailing =
Store code_verifier in sessionStorage (not localStorage) — so the verifier doesn't persist after the tab closes or leak to other tabs (security: the verifier is a one-time secret)
Your app's URL (where the user returns after auth)
code_challenge
The S256 challenge from Step 1
code_challenge_method
Always S256
Step 3: Handle the redirect back
User returns to your callback_url with ?code= appended. Extract the code query parameter.
Important: Before processing ?code=, check that a code_verifier exists in sessionStorage. Other routes or third-party code might use ?code= query params for unrelated purposes — a hasOAuthCallbackPending() guard ensures you only consume codes that belong to your OAuth flow.
Step 4: Exchange code for API key
POST https://openrouter.ai/api/v1/auth/keys
Content-Type: application/json
{
"code": "<code from query param>",
"code_verifier": "<verifier from sessionStorage>",
"code_challenge_method": "S256"
}
→ { "key": "sk-or-..." }
Remove the verifier from sessionStorage before or after the exchange.
Step 5: Store the key and clean up
Store key in localStorage
Clean the URL: history.replaceState({}, "", location.pathname) to remove ?code=
Cross-tab sync: Listen for storage events on the API key's localStorage entry so other tabs update when the user signs in or out
Auth Module Reference
Drop-in module implementing the full PKCE flow. Reduces risk of getting base64url encoding, sessionStorage handling, or the key exchange wrong.
Show a loading indicator while the key exchange is in progress. Default label: "Sign in with OpenRouter".
Dark mode
For dark mode support, add dark variants: swap light backgrounds to dark (dark:bg-neutral-900 dark:text-white) and vice versa for branded/cta (dark:bg-white dark:text-neutral-900).