πŸ”PKCE Implementation Guide

This comprehensive guide covers implementing PKCE (Proof Key for Code Exchange) for Single Page Applications (SPAs) and native mobile applications using Oten IDP.

Table of Contents

Overview

PKCE (Proof Key for Code Exchange) is a security extension to OAuth 2.0 that prevents authorization code interception attacks. It's required for public clients that cannot securely store client secrets.

What is PKCE?

PKCE works by generating a cryptographically random string called a "code verifier" and its derived "code challenge". The code challenge is sent with the authorization request, and the code verifier is sent with the token request to prove that the same client that initiated the flow is completing it.

Key Benefits

  • Prevents authorization code interception attacks

  • No client secret required for public clients

  • Works with custom URL schemes in mobile apps

  • Compatible with all OAuth 2.0 flows

  • Recommended by OAuth 2.1 for all clients

When to Use PKCE

βœ… Always Use PKCE For:

  • Single Page Applications (SPAs)

    • React, Vue, Angular applications

    • Vanilla JavaScript applications

    • Progressive Web Apps (PWAs)

  • Native Mobile Applications

    • iOS applications (Swift, Objective-C)

    • Android applications (Kotlin, Java)

    • Cross-platform apps (React Native, Flutter, Xamarin)

  • Desktop Applications

    • Electron applications

    • Native desktop apps with embedded browsers

⚠️ Consider PKCE For:

  • Server-side applications (additional security layer)

  • Hybrid applications with both server and client components

PKCE Flow Diagrams

SPA PKCE Flow

SPA PKCE Flow

Native App PKCE Flow

Native App PKCE Flow

API Reference

PKCE Parameters

Authorization Request Parameters

Parameter
Required
Description
Example

code_challenge

Yes

Base64URL-encoded SHA256 hash of code_verifier

"E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

code_challenge_method

Yes

Hash method used for code_challenge

"S256" (only supported method)

Token Request Parameters

Parameter
Required
Description
Example

code_verifier

Yes

Original random string used to generate code_challenge

"dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

Code Verifier Requirements

  • Length: 43-128 characters

  • Characters: [A-Z], [a-z], [0-9], -, ., _, ~

  • Entropy: Minimum 256 bits of entropy

  • Generation: Use cryptographically secure random number generator

Code Challenge Generation

Where:

  • SHA256() is the SHA256 hash function

  • BASE64URL() is base64url encoding (RFC 4648 Section 5)

Endpoints

Authorization Endpoint

Parameters (Direct in URL for Public Clients):

  • Standard OAuth 2.0 parameters

  • PKCE parameters (code_challenge, code_challenge_method)

Token Endpoint

Request Body (application/x-www-form-urlencoded):

Note: No client_secret required for public clients using PKCE.

Discovery Configuration

Oten IDP supports OpenID Connect Discovery. The configuration is available at:

Key PKCE-related fields:

SPA Implementation

Vanilla JavaScript Implementation

Complete PKCE Helper Class

Usage Example

React Implementation

React Hook for PKCE Authentication

React Component Examples

Vue.js Implementation

Vue Composition API

Native App Implementation

iOS Implementation (Swift)

PKCE Helper Class

SwiftUI Usage Example

Android Implementation (Kotlin)

PKCE Authentication Manager

Android Activity Usage Example

Security Considerations

PKCE Security Best Practices

Code Verifier Generation

Secure Storage

SPAs:

Native Apps:

State Parameter Validation

Token Expiration Handling

Common Security Pitfalls

1. Insufficient Code Verifier Entropy

2. Code Verifier Leakage

3. Improper Redirect URI Validation

4. Missing HTTPS Enforcement

Platform-Specific Security

SPA Security

  • Content Security Policy (CSP): Implement strict CSP headers

  • Subresource Integrity (SRI): Use SRI for external scripts

  • HTTPS Only: Never use HTTP in production

  • Session Storage: Use sessionStorage, not localStorage for temporary data

Native App Security

  • Custom URL Schemes: Use app-specific schemes (e.g., com.yourcompany.yourapp://)

  • Certificate Pinning: Pin SSL certificates for API calls

  • App Transport Security: Enable ATS on iOS

  • Network Security Config: Configure secure networking on Android

  • Secure Storage: Always use Keychain (iOS) or Keystore (Android)

Error Handling

Common PKCE Errors

Authorization Endpoint Errors

Error Code
Description
Cause
Solution

invalid_request

Missing or invalid PKCE parameters

Missing code_challenge or code_challenge_method

Ensure PKCE parameters are included in JAR

invalid_request

Invalid code challenge method

Using unsupported method (not S256)

Always use code_challenge_method: "S256"

invalid_client

Client authentication failed

Invalid client_id or JAR signature

Verify client_id and JAR signing

Token Endpoint Errors

Error Code
Description
Cause
Solution

invalid_grant

Code verifier validation failed

code_verifier doesn't match code_challenge

Ensure same verifier used for challenge generation

invalid_grant

Authorization code not issued with PKCE

Code was issued without PKCE but verifier provided

Always include PKCE in authorization request

invalid_request

Missing code verifier

PKCE required but code_verifier not provided

Include code_verifier in token request

Error Handling Implementation

JavaScript Error Handling

Testing and Validation

PKCE Implementation Testing

Unit Tests for PKCE Generation

Integration Tests

Manual Testing Checklist

Pre-Implementation Testing

PKCE Flow Testing

Security Testing

Troubleshooting

Common Issues and Solutions

1. "Invalid code verifier" Error

Symptoms:

  • Token exchange fails with invalid_grant error

  • Error description mentions code verifier validation

Causes:

  • Code verifier doesn't match the one used to generate code challenge

  • Code verifier was modified or corrupted during storage

  • Different code verifier used between authorization and token requests

Solutions:

2. "Missing code challenge" Error

Symptoms:

  • Authorization request fails with invalid_request

  • Error mentions missing PKCE parameters

Causes:

  • PKCE parameters not included in JAR

  • JAR creation doesn't include code challenge

  • Code challenge is null or undefined

Solutions:

3. State Parameter Mismatch

Symptoms:

  • Callback handling fails with CSRF error

  • State validation throws error

Causes:

  • State parameter was modified during redirect

  • Multiple login attempts with same state

  • Session storage cleared between requests

Solutions:

4. JAR Creation Failures

Symptoms:

  • Authorization flow fails before redirect

  • JAR endpoint returns errors

Causes:

  • Invalid client credentials

  • Malformed JAR payload

  • Network connectivity issues

Solutions:

Symptoms:

  • App doesn't receive callback on mobile

  • Deep link not triggering app

iOS Solutions:

Android Solutions:

Debug Tools and Techniques

PKCE Parameter Validation

Network Request Debugging

Security Considerations

Code Verifier Security

  • Generate with sufficient entropy: Use at least 256 bits of entropy

  • Use cryptographically secure random generators: Never use Math.random()

  • Store securely: Use secure storage mechanisms (Keychain, Keystore, sessionStorage)

  • Never log or expose: Code verifiers should never appear in logs or URLs

State Parameter Protection

  • Always use unique state: Generate a new state for each authorization request

  • Validate on callback: Always verify the state parameter matches

  • Use sufficient entropy: State should be unpredictable and unique

Transport Security

  • HTTPS only: Never use HTTP for OAuth flows in production

  • Validate redirect URIs: Ensure redirect URIs are properly validated

  • Secure storage: Use appropriate secure storage for tokens and sensitive data

Error Handling

Common PKCE Errors

invalid_request

  • Cause: Missing or malformed PKCE parameters

  • Solution: Ensure code_challenge and code_challenge_method are included

invalid_grant

  • Cause: Code verifier doesn't match the challenge

  • Solution: Verify the same code verifier is used throughout the flow

unsupported_code_challenge_method

  • Cause: Using unsupported challenge method

  • Solution: Only use S256 method

Error Recovery Strategies

Testing and Validation

Unit Testing PKCE Components

Integration Testing

Manual Testing Checklist

Troubleshooting

Debug Mode Setup

Common Issues and Solutions

Issue: "Code challenge mismatch"

Symptoms: Token exchange fails with invalid_grant Causes:

  • Different code verifier used in token request

  • Code verifier corrupted during storage

  • Multiple authorization flows running simultaneously

Solutions:

  • Ensure single source of truth for code verifier

  • Validate storage/retrieval mechanisms

  • Clear stored parameters before new flow

Issue: "State parameter mismatch"

Symptoms: Callback validation fails Causes:

  • State not properly stored

  • Multiple browser tabs/windows

  • Session storage cleared

Solutions:

  • Use sessionStorage for SPAs

  • Implement proper state management

  • Handle multiple tab scenarios

Issue: "Redirect URI mismatch"

Symptoms: Authorization fails immediately Causes:

  • Redirect URI not registered

  • HTTP vs HTTPS mismatch

  • Port number differences

Solutions:

  • Verify client configuration

  • Ensure exact URI match

  • Use dynamic port handling for development

Debugging Tools

References and Further Reading

Standards and Specifications

Security Guidelines

Implementation Resources


Need Help? Contact our Support Team for assistance with PKCE implementation.

Last updated