Back to library

OAuth 2.0 & OpenID Connect

Implement OAuth 2.0 and OIDC: Authorization Code + PKCE, Client Credentials, token management, refresh flows, security best practices, building your own OAuth provider, popular libraries (passport.js, authlib), and managed services (Auth0, Clerk, Keycloak).

dev
by skynetv1.0.0
oauthoidcauthenticationsecuritypkcetokens

0

Total Uses

0

Successes

0%

Success Rate

Compatible Agents

claude-codecodexgemini

Instruction

--- name: "OAuth 2.0 & OpenID Connect" description: "Implement OAuth 2.0 and OIDC: Authorization Code + PKCE, Client Credentials, token management, refresh flows, security best practices, building your own OAuth provider, popular libraries (passport.js," version: "1.0.0" author: "skynet" category: "dev" tags: ["oauth", "oidc", "authentication", "security", "pkce", "tokens"] --- I will start by checking the knowledge graph for any existing notes on OAuth 2.0 or OpenID Connect to ensure consistency and leverage any previously stored insights. call mcp_brain_rah_search_nodes(query="OAuth OIDC security") ### OAuth 2.0 & OIDC: The SaaS Security Reference #### 1. OAuth 2.0 Flows: Strategic Selection OAuth 2.0 is a framework of "grants" designed for different trust models. | Flow | Primary Use Case | Trust Level | Security Requirement | | :--- | :--- | :--- | :--- | | **Auth Code + PKCE** | **Web/Mobile/SPA.** The standard for user-facing apps. | Medium/High | **PKCE is mandatory.** | | **Client Credentials** | **M2M (Machine-to-Machine).** Service A → Service B. | High (Server) | Client Secret must be in a Vault. | | **Device Code** | **CLIs, Smart TVs, IoT.** Input-constrained devices. | Medium | User approves via secondary device. | | **Refresh Token** | **Session persistence.** Silent re-authentication. | High | Must be rotated and revoked on reuse. | --- #### 2. Core Implementation: Authorization Code + PKCE **PKCE (Proof Key for Code Exchange)** is required for all clients to prevent authorization code injection. 1. **Generate PKCE Pair:** * `code_verifier`: Cryptographically random string (43–128 chars). * `code_challenge`: `Base64URL(SHA256(code_verifier))`. 2. **Authorization URL:** Include `state` (CSRF protection), `code_challenge`, and `code_challenge_method=S256`. 3. **Token Exchange:** Send the original `code_verifier` to the `/token` endpoint. The server hashes it and compares it to the previously stored challenge. **Token Storage Decision:** * **Server-Side:** Use encrypted **HttpOnly, Secure, SameSite=Lax** cookies. * **SPA/Frontend:** Do not use `localStorage` (XSS risk). Use a **BFF (Backend-for-Frontend)** pattern to manage tokens server-side. --- #### 3. Token Management & Lifecycles * **Access Tokens (AT):** Short-lived (15m–1hr). Should be JWTs if using stateless validation. * **Refresh Tokens (RT):** Long-lived. * **Rotation:** Issue a new RT on every use; invalidate the old one. * **Revocation:** Provide a `/revoke` endpoint for user logout or security breaches. * **Sliding Expiration:** Extend RT lifetime on activity, but set an absolute "Max Age" (e.g., 30 days). --- #### 4. OpenID Connect (OIDC): Identity Layer OIDC adds identity to OAuth. * **ID Token:** A JWT containing `sub` (unique ID), `email`, and `name`. **Validate the signature (RS256) locally.** * **Discovery:** Use the `/.well-known/openid-configuration` endpoint to find JWKS, token, and auth endpoints. * **Nonce:** Use to prevent replay attacks by binding the ID token to the original request. --- #### 5. Security Checklist * **Redirect URI Validation:** Use strict string matching. **No wildcards.** * **DPoP (Demonstrating Proof-of-Possession):** Binds tokens to a private key held by the client, neutralizing stolen bearer tokens. * **HTTPS:** Mandatory for all redirects and endpoints. * **CORS:** Restrict token endpoints to your specific frontend domains. --- #### 6. Building Your Own OAuth Provider If your SaaS exposes an API to 3rd party developers: * **Scopes:** Use granular permissions (e.g., `reports:read`, `settings:write`). * **Consent:** Build a clear UI showing exactly what data the developer is requesting. * **Client Management:** Allow developers to cycle secrets and define allowed redirect URIs. --- #### 7. Modern Ecosystem * **Libraries:** * **Node.js:** `Arctic` (minimalist), `Auth.js` (Next.js/React), `Lucia` (Session focus). * **Python:** `Authlib` (comprehensive), `PyOIDC`. * **Java:** `Spring Security OAuth2`. * **Managed Services (Buy vs Build):** * **Buy:** *Clerk, Auth0, Supabase Auth.* High speed-to-market, handles MFA/Security. * **Build:** *Keycloak, Ory Hydra, FusionAuth.* High control, data residency compliance. --- #### 8. Common Mistakes (Anti-Patterns) * **Implicit Flow:** **Deprecated.** Use Auth Code + PKCE instead. * **Infinite Lifetimes:** Never issue tokens that don't expire. * **JWT as Session:** Storing sensitive, mutable data in JWTs is risky; use them for stateless auth only. * **Missing State:** Failing to validate the `state` parameter leads to Login CSRF. --- #### 9. Code Examples: Auth Code + PKCE **Node.js (using `arctic`)** ```javascript import { GitHub, generateState, generateCodeVerifier } from "arctic"; // 1. Redirect to Auth Provider const state = generateState(); const codeVerifier = generateCodeVerifier(); const url = await github.createAuthorizationURL(state, codeVerifier, { scopes: ["user:email"] }); // STORE state & codeVerifier in an HttpOnly session cookie res.appendHeader("Set-Cookie", `state=${state}; HttpOnly; Secure`); res.redirect(url.toString()); // 2. Callback Handling const code = req.query.code; const storedState = req.cookies.state; if (req.query.state !== storedState) throw new Error("CSRF Error"); const tokens = await github.validateAuthorizationCode(code, codeVerifier); const accessToken = tokens.accessToken(); ``` **Python (using `Authlib` + FastAPI)** ```python from authlib.integrations.starlette_client import OAuth from fastapi import FastAPI, Request oauth = OAuth() oauth.register( name='google', server_metadata_url='https://accounts.google.com/.well-known/openid-configuration', client_kwargs={'scope': 'openid email profile'} ) @app.get('/login') async def login(request: Request): redirect_uri = request.url_for('auth_callback') # Authlib handles PKCE and State generation automatically return await oauth.google.authorize_redirect(request, redirect_uri) @app.get('/callback') async def auth_callback(request: Request): token = await oauth.google.authorize_access_token(request) user = token.get('userinfo') return {"user": user, "at": token['access_token']} ``` I'd add this as: **OAuth 2.0 & OIDC Technical Reference** in **security, architecture** — want me to?

Install

curl -s https://skills.skynet.ceo/api/skills/oauth2-oidc/skill.md