Use OAuth 2.0 Playground

Enter your data below to use the OAuth 2.0 Playground

📌 Try these examples:
RESULT

Last updated

Authorization Code Flow — Step by Step

The most common OAuth 2.0 flow for server-side applications:

Step 1: Build the authorization URL
GET https://auth.example.com/oauth/authorize?
  response_type=code
  &client_id=my_client_id
  &redirect_uri=https://myapp.com/callback
  &scope=read:user read:email
  &state=xK9mP2qR7vN4wL8j  (random CSRF token)

Step 2: User logs in and approves — server redirects to:
https://myapp.com/callback?
  code=SplxlOBeZQQYbYS6WxSbIA
  &state=xK9mP2qR7vN4wL8j

Step 3: Exchange code for tokens
POST https://auth.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https://myapp.com/callback
&client_id=my_client_id
&client_secret=my_client_secret

Step 4: Token response
{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
  "scope": "read:user read:email"
}

PKCE — Authorization Code with Proof Key

The secure extension for public clients (SPAs, mobile apps):

Step 1: Generate code verifier and challenge
code_verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
code_challenge = BASE64URL(SHA256(code_verifier))
             = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

Step 2: Authorization request (include challenge)
GET https://auth.example.com/oauth/authorize?
  response_type=code
  &client_id=my_spa_client
  &redirect_uri=https://myapp.com/callback
  &scope=read:user
  &state=xK9mP2qR7vN4wL8j
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

Step 3: Token exchange (include verifier, no client_secret needed)
POST https://auth.example.com/oauth/token
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https://myapp.com/callback
&client_id=my_spa_client
&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

PKCE prevents authorization code interception attacks. Even if an attacker intercepts the code, they cannot exchange it without the code verifier.

Client Credentials Flow (Machine-to-Machine)

For server-to-server API calls with no user involved:

POST https://auth.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)

grant_type=client_credentials
&scope=api:read api:write

Response:
{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "api:read api:write"
}

No refresh token is issued — just request a new access token when the current one expires. This flow is used for microservice-to-microservice authentication and background jobs.

Token Refresh Flow

Get a new access token using a refresh token (no user re-authentication needed):

POST https://auth.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
&client_id=my_client_id
&client_secret=my_client_secret

Response:
{
  "access_token": "eyJhbGciOiJSUzI1NiJ9...NEW...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "new_refresh_token_value"  // Rotation
}

Refresh token rotation issues a new refresh token with each use. Store the new refresh token and discard the old one. If the old token is used again, it indicates token theft and the server should revoke all tokens.

JWT Access Token Inspection

Decode a JWT to see its claims:

Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfMTIzIiwic2NvcGUiOiJyZWFkOnVzZXIiLCJleHAiOjE3MTA2OTYwMDB9.signature

Header:
{
  "alg": "RS256",
  "typ": "JWT"
}

Payload:
{
  "sub": "usr_123",           // Subject (user ID)
  "iss": "https://auth.example.com",
  "aud": "https://api.example.com",
  "scope": "read:user read:email",
  "exp": 1710696000,          // Expires: 2024-03-17T12:00:00Z
  "iat": 1710692400,          // Issued at
  "jti": "V1StGXR8_Z5jdHi6B" // JWT ID (for revocation)
}

The playground decodes the token and shows the expiration time in human-readable format. Check that the scope contains the permissions your API requires before accepting the token.

State Parameter — CSRF Protection

The state parameter prevents cross-site request forgery attacks:

// 1. Generate random state before redirecting
const state = crypto.randomBytes(16).toString('hex');
// state = "a3f7b2c1d4e5f6a7b8c9d0e1f2a3b4c5"

// 2. Store in session
session.oauthState = state;

// 3. Include in authorization URL
const authUrl = `https://auth.example.com/authorize?...&state=${state}`;

// 4. In callback — verify state matches
if (req.query.state !== session.oauthState) {
  return res.status(403).send('CSRF attack detected');
}
// Proceed with code exchange

OAuth Error Responses

Common error responses and what they mean:

// User denied authorization
https://myapp.com/callback?
  error=access_denied
  &error_description=The+user+denied+access
  &state=xK9mP2qR7vN4wL8j

// Invalid client credentials
{
  "error": "invalid_client",
  "error_description": "Client authentication failed"
}

// Authorization code expired (codes typically expire in 10 minutes)
{
  "error": "invalid_grant",
  "error_description": "Authorization code has expired"
}

// Requested scope not available
{
  "error": "invalid_scope",
  "error_description": "The requested scope is invalid or unknown"
}

Device Authorization Flow

For devices without a browser (smart TVs, CLI tools):

Step 1: Request device code
POST https://auth.example.com/oauth/device/code
client_id=my_device_client
&scope=read:user

Response:
{
  "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://auth.example.com/device",
  "expires_in": 900,
  "interval": 5
}

Step 2: Show user_code to user
"Visit https://auth.example.com/device and enter: WDJB-MJHT"

Step 3: Poll for token every 5 seconds
POST https://auth.example.com/oauth/token
grant_type=urn:ietf:params:oauth:grant-type:device_code
&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS
&client_id=my_device_client

// While waiting: { "error": "authorization_pending" }
// After approval: { "access_token": "...", ... }

Using the Access Token

Include the token in API requests as a Bearer token:

GET https://api.example.com/user/profile
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...

// Response
{
  "id": "usr_123",
  "name": "[name]",
  "email": "[email]"
}

Never put access tokens in URL query parameters — they appear in server logs and browser history. Always use the Authorization header.

Frequently Asked Questions

Simply enter your data, click the process button, and get instant results. All processing happens in your browser for maximum privacy and security.

Yes! OAuth 2.0 Playground is completely free to use with no registration required. All processing is done client-side in your browser.

Absolutely! All processing happens locally in your browser. Your data never leaves your device, ensuring complete privacy and security.