Implicit Flow
The implicit flow is a simplified OAuth 2.0 authorization flow originally designed for browser-based applications (single-page applications) that cannot securely store client secrets. It’s defined in RFC 6749 Section 4.2.
When to use implicit flow
Section titled “When to use implicit flow”The implicit flow should only be considered for:
- Legacy applications that cannot be updated to use the authorization code flow with PKCE
- Compatibility requirements with older OAuth libraries that don’t support PKCE
- Specific compliance scenarios where implicit flow is mandated
For all new development, use the authorization code flow with PKCE.
How implicit flow works
Section titled “How implicit flow works”Unlike the authorization code flow, which returns a code that is then exchanged for tokens, the implicit flow returns tokens directly from the authorization endpoint:
- Client redirects user to the authorization endpoint with
response_type=token(orid_tokenorid_token token) - User authenticates and grants consent (if required)
- Authorization server redirects back to the client with tokens in the URL fragment (the part after
#) - Client extracts tokens from the URL fragment using JavaScript
https://your-app.com/callback#access_token=eyJhbG...&token_type=Bearer&expires_in=3600&state=abc123Security considerations
Section titled “Security considerations”The implicit flow has several security limitations compared to the authorization code flow:
Tokens exposed in URLs
Section titled “Tokens exposed in URLs”Tokens are returned in the URL fragment, which means they can be:
- Visible in browser history
- Logged by intermediate proxies (though fragments are typically not sent to servers)
- Accessed by malicious JavaScript on the page
No refresh tokens
Section titled “No refresh tokens”Per RFC 6749 Section 4.2.2, the authorization server must not issue refresh tokens for the implicit grant. This means:
- Users must re-authenticate when access tokens expire
- Applications cannot silently refresh tokens in the background
- Shorter session durations are harder to manage
Limited token lifetime
Section titled “Limited token lifetime”Access tokens from implicit flow should have short expiration times to minimize the window of exposure if a token is compromised.
No client authentication
Section titled “No client authentication”Since the implicit flow is designed for public clients that cannot store secrets, there is no client authentication. This means any application that knows your client ID could potentially initiate an authorization request.
Supported response types
Section titled “Supported response types”Goiabada supports the following response types for implicit flow:
| Response Type | Description | Returns |
|---|---|---|
token | OAuth 2.0 implicit grant | Access token only |
id_token | OpenID Connect implicit flow | ID token only |
id_token token | OpenID Connect implicit flow | Both ID token and access token |
Response type: token
Section titled “Response type: token”Use this when you only need an access token to call APIs:
GET /auth/authorize? client_id=my-spa& redirect_uri=https://my-app.com/callback& response_type=token& scope=openid profile& state=abc123Response type: id_token
Section titled “Response type: id_token”Use this when you only need to authenticate the user and get identity claims:
GET /auth/authorize? client_id=my-spa& redirect_uri=https://my-app.com/callback& response_type=id_token& scope=openid profile& state=abc123& nonce=xyz789Response type: id_token token
Section titled “Response type: id_token token”Use this when you need both authentication and API access:
GET /auth/authorize? client_id=my-spa& redirect_uri=https://my-app.com/callback& response_type=id_token%20token& scope=openid profile& state=abc123& nonce=xyz789When both tokens are returned, the ID token includes an at_hash claim containing a hash of the access token, allowing the client to verify that the access token was issued together with the ID token (per OIDC Core Section 3.2.2.10).
Parameters
Section titled “Parameters”Authorization request
Section titled “Authorization request”| Parameter | Required | Description |
|---|---|---|
client_id | Yes | The client identifier |
redirect_uri | Yes | Must exactly match a registered redirect URI |
response_type | Yes | token, id_token, or id_token token |
scope | Yes | Space-separated scopes. Must include openid for id_token |
state | Recommended | Random string for CSRF protection, echoed back in response |
nonce | Conditional | Required when requesting id_token. Included in the ID token for replay protection |
Success response
Section titled “Success response”Tokens are returned in the URL fragment:
| Parameter | Description |
|---|---|
access_token | The access token (if requested) |
token_type | Always Bearer |
expires_in | Token lifetime in seconds |
id_token | The ID token JWT (if requested) |
state | Echo of the state parameter from the request |
scope | The granted scopes (may differ from requested) |
Error response
Section titled “Error response”Errors are also returned in the URL fragment:
| Parameter | Description |
|---|---|
error | Error code (e.g., unauthorized_client, invalid_request) |
error_description | Human-readable error description |
state | Echo of the state parameter from the request |
Configuration
Section titled “Configuration”Enabling implicit flow
Section titled “Enabling implicit flow”By default, implicit flow is disabled for security reasons. To enable it:
Global setting
Section titled “Global setting”- Navigate to Settings → General in the admin console
- Enable “Implicit flow”
- Save changes
This enables implicit flow for all clients that inherit from the global setting.
Per-client setting
Section titled “Per-client setting”Individual clients can override the global setting:
- Navigate to Clients → [Client Name] → OAuth2 flows in the admin console
- Under “Implicit flow”, choose:
- Inherit from global setting - Uses the global configuration
- Enabled - This client can use implicit flow regardless of global setting
- Disabled - This client cannot use implicit flow regardless of global setting
- Save changes
Error when disabled
Section titled “Error when disabled”If a client attempts to use implicit flow when it’s not enabled, the authorization server returns an error:
https://your-app.com/callback#error=unauthorized_client&error_description=The+client+is+not+authorized+to+use+the+implicit+grant+type...&state=abc123Validating tokens
Section titled “Validating tokens”Validating ID tokens
Section titled “Validating ID tokens”When receiving an ID token from implicit flow, validate:
- Signature - Verify the JWT signature using the authorization server’s public key (available at the JWKS endpoint)
- Issuer (
iss) - Must match your authorization server’s issuer - Audience (
aud) - Must contain your client ID - Expiration (
exp) - Token must not be expired - Nonce - Must match the nonce you sent in the authorization request
at_hash- If access token was also returned, verify the at_hash claim
Validating at_hash
Section titled “Validating at_hash”When response_type=id_token token, the ID token contains an at_hash claim. To validate it:
- Hash the access token using SHA-256
- Take the left half (first 128 bits) of the hash
- Base64url-encode without padding
- Compare with the
at_hashclaim in the ID token
const crypto = require('crypto');
function validateAtHash(accessToken, atHashFromIdToken) { const hash = crypto.createHash('sha256').update(accessToken).digest(); const leftHalf = hash.slice(0, hash.length / 2); const expectedAtHash = leftHalf.toString('base64url'); return expectedAtHash === atHashFromIdToken;}Migration to authorization code flow
Section titled “Migration to authorization code flow”If you’re currently using implicit flow, consider migrating to authorization code flow with PKCE:
- Update your OAuth library - Most modern OAuth/OIDC libraries support PKCE
- Change response_type - Switch from
tokenorid_token tokentocode - Implement PKCE - Generate code verifier and challenge (see PKCE documentation)
- Add token exchange - After receiving the code, exchange it for tokens at the token endpoint
- Handle refresh tokens - You can now silently refresh tokens without user interaction
The authorization code flow with PKCE provides:
- Tokens are not exposed in URLs
- Refresh tokens for longer sessions
- Better protection against token interception
Best practices
Section titled “Best practices”If you must use implicit flow:
- Use short token lifetimes - Minimize the impact of token compromise
- Always use state parameter - Protect against CSRF attacks
- Always use nonce for id_token - Protect against replay attacks
- Validate at_hash - When receiving both id_token and access_token
- Clear the URL fragment - Remove tokens from browser history after extraction
- Use HTTPS only - Never use implicit flow over unencrypted connections
- Consider Content Security Policy - Restrict which scripts can run on your page
- Plan for migration - Treat implicit flow as temporary while planning PKCE adoption