Overview
SuperTokens Core provides a complete OAuth 2.0 implementation that can function as both an authorization server and OAuth client. The implementation is built on top of Ory Hydra and includes token management, introspection, and revocation capabilities.OAuth 2.0 as Authorization Server
SuperTokens can act as an OAuth 2.0 authorization server, allowing your application to issue OAuth tokens to third-party applications.Client Management
Create or Update OAuth Client
Implementation:io.supertokens.oauth.OAuth.addOrUpdateClient() - View source
API Endpoint:
POST /recipe/oauth/clients
Request Body:
- Client secret encryption at rest
- Support for client credentials grant
- Refresh token rotation
- Multi-tenancy support
List OAuth Clients
API Endpoint: GET/recipe/oauth/clients?clientIds=client1,client2
Response:
Remove OAuth Client
API Endpoint: POST/recipe/oauth/clients/remove
Request Body:
Authorization Flow
Authorization Request
Initiate the OAuth authorization flow. API Endpoint: GET/recipe/oauth/auth
Query Parameters:
client_id: OAuth client identifierredirect_uri: Callback URLresponse_type: “code” for authorization code flowscope: Requested scopes (space-separated)state: CSRF protection tokencode_challenge: PKCE challenge (optional)code_challenge_method: “S256” for SHA-256 (optional)
Token Exchange
Exchange authorization code for access tokens. Implementation:io.supertokens.oauth.OAuth.doOAuthProxyFormPOST() - View source
API Endpoint:
POST /recipe/oauth/token
Request Body (Authorization Code Grant):
Token Management
Token Introspection
Validate and inspect access tokens. Implementation:io.supertokens.oauth.OAuth.introspectAccessToken() - View source
API Endpoint:
POST /recipe/oauth/introspect
Request Body:
Token Revocation
Revoke access tokens, refresh tokens, or entire sessions. Revoke Refresh Token: Implementation:io.supertokens.oauth.OAuth.revokeRefreshToken() - View source
POST /recipe/oauth/tokens/revoke
io.supertokens.oauth.OAuth.revokeAccessToken() - View source
POST /recipe/oauth/token/revoke
io.supertokens.oauth.OAuth.revokeSessionHandle() - View source
POST /recipe/oauth/session/revoke
io.supertokens.oauth.OAuth.revokeTokensForClientId() - View source
POST /recipe/oauth/tokens/revoke
Token Structure
Access Token
Access tokens are signed JWTs with the following structure: Header:sub: Subject (user ID)iss: Issuer (your domain)aud: Audience (client IDs)exp: Expiration timeiat: Issued at timejti: JWT ID (unique token identifier)gid: Group ID (session identifier)stt: SuperTokens token type (1 = access token)client_id: OAuth client IDscope: Granted scopes
ID Token
ID tokens are signed JWTs containing user identity information: Payload:sub: Subject (user ID)iss: Issueraud: Audience (client ID)exp: Expirationiat: Issued atauth_time: Authentication timenonce: Request nonceat_hash: Access token hash (for implicit/hybrid flows)
Refresh Token
Refresh tokens are opaque strings with the format:- Long-lived (configurable)
- One-time use (with rotation)
- Mapped to internal Hydra tokens
- Revocable by session or client
Token Signing
Static Signing Key
Use a static RSA key for token signing:- Consistent key ID
- Simpler key management
- Better caching
Dynamic Signing Key
Use rotating keys for enhanced security:- Key rotation
- Compromised key isolation
- Enhanced security
Client Secret Encryption
Client secrets are encrypted at rest using AES-256-GCM. Configuration:io.supertokens.oauth.OAuth.encryptClientSecret() - View source
PKCE Support
Proof Key for Code Exchange (PKCE) is supported for public clients. Flow:- Client generates code verifier:
- Client creates code challenge:
- Authorization request includes challenge:
- Token request includes verifier:
Logout Flow
Implementation:io.supertokens.oauth.OAuth.createLogoutRequestAndReturnRedirectUri() - View source
Create Logout Request:
POST /recipe/oauth/logout
Request Body:
io.supertokens.oauth.OAuth.consumeLogoutChallengeAndGetRedirectUri() - View source
Configuration
OAuth Provider URLs
Security Features
Token Revocation
Tokens can be revoked:- By JTI (access token ID)
- By GID (session ID)
- By client ID
- By session handle
io.supertokens.oauth.OAuth.isTokenRevokedBasedOnPayload() - View source
State Parameter
Always validate state parameter to prevent CSRF:Redirect URI Validation
Redirect URIs must:- Match exactly (no wildcards)
- Be registered with the client
- Use HTTPS in production
M2M Token Tracking
Track machine-to-machine (client credentials) tokens for analytics. Implementation:io.supertokens.oauth.OAuth.addM2MToken() - View source
Error Handling
OAuth Errors
Implemented inio.supertokens.oauth.exceptions.OAuthAPIException.
Common Errors:
invalid_request: Malformed requestinvalid_client: Client authentication failedinvalid_grant: Invalid authorization code or refresh tokenunauthorized_client: Client not authorized for grant typeunsupported_grant_type: Grant type not supportedinvalid_scope: Requested scope is invalidaccess_denied: User denied authorization
Best Practices
- Use PKCE: Always use PKCE for public clients
- Rotate secrets: Regularly rotate client secrets
- Short-lived tokens: Keep access tokens short-lived (15-60 minutes)
- Refresh token rotation: Enable rotation for security
- Validate state: Always validate state parameter
- HTTPS only: Never use OAuth over HTTP in production
- Minimal scopes: Request only necessary scopes
- Revoke on logout: Revoke tokens when user logs out
- Monitor usage: Track token usage for security
- Encrypt secrets: Store client secrets encrypted
Multi-Tenancy
OAuth clients are tenant-specific:- Each tenant has isolated OAuth clients
- Token validation respects tenant boundaries
- Client IDs must be unique per tenant
- Tokens include tenant context