Files
gh-varaku1012-aditi-code-pl…/commands/oauth-troubleshoot.md
2025-11-30 09:04:20 +08:00

11 KiB

description
description
Troubleshooting guide for common Auth0 OAuth issues

OAuth Troubleshooting Guide

Solutions for common Auth0 OAuth problems.

Quick Start

/oauth-troubleshoot [issue]

Common issues:

  • callback-mismatch - Callback URL doesn't match
  • token-expired - Access token expired
  • cors-error - CORS error when calling API
  • silent-auth - Silent authentication not working
  • scope-error - Scope not in token
  • mfa-required - MFA login failing
  • logout-not-clearing - Session not cleared on logout
  • social-login-fails - Social login buttons not working

Issue: Callback URL Mismatch

Error: "Unable to process redirect request" or "Invalid redirect_uri"

Cause: Redirect URL in Auth0 doesn't match your app's callback URL

Solution:

  1. Check your app's callback URL:

    // React
    <Auth0Provider
      authorizationParams={{
        redirect_uri: window.location.origin + '/callback'
      }}
    >
    
    // Next.js
    AUTH0_CALLBACK_URL=http://localhost:3000/api/auth/callback
    
  2. Update Auth0 Dashboard:

    Auth0 Dashboard → Applications → Your App → Settings
    
    Allowed Callback URLs:
    http://localhost:3000/callback
    OR
    http://localhost:3000/api/auth/callback
    
    (Must EXACTLY match your app!)
    
  3. Common mistakes:

    • Including query params: /callback?foo=bar (wrong!)
    • Using http:// vs https://
    • Port number mismatch: :3000 vs :3001
    • Missing trailing slash inconsistency
  4. Test:

    # Verify URL matches exactly
    echo "App uses: window.location.origin + '/callback'"
    echo "Current: $CALLBACK_URL"
    

Issue: Access Token Expired

Error: API returns 401 Unauthorized

Cause: Access token expired (default 10 minutes)

Solution:

  1. Use Auth0 SDK (auto-refresh):

    // React
    const { getAccessTokenSilently } = useAuth0()
    const token = await getAccessTokenSilently()  // Auto-refreshes if expired
    
    // Next.js
    const session = await getSession()  // SDK handles refresh
    const token = session.accessToken
    
  2. Verify token expiration:

    Auth0 Dashboard → Applications → Settings → Token Expiration
    
    Should be: 600 (10 minutes)
    Refresh Token Expiration: 2592000 (30 days)
    Refresh Token Rotation: Enabled ✅
    
  3. Manual refresh (if needed):

    async function getRefreshToken() {
      const response = await fetch(`https://${AUTH0_DOMAIN}/oauth/token`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          client_id: CLIENT_ID,
          client_secret: CLIENT_SECRET,
          refresh_token: refreshToken,
          grant_type: 'refresh_token'
        })
      })
    
      const { access_token } = await response.json()
      return access_token
    }
    
  4. Test:

    # Decode token to check expiration
    # Visit https://jwt.io and paste your access token
    # Look at "exp" claim (Unix timestamp)
    

Issue: CORS Error Calling API

Error: "Access to XMLHttpRequest blocked by CORS policy"

Cause 1: Backend CORS not configured for frontend origin

Solution 1 (Express/Node.js):

import cors from 'cors'

// Allow specific origins
app.use(cors({
  origin: ['http://localhost:3000', 'https://myapp.com'],
  credentials: true  // Important for cookies
}))

// Or check origin dynamically
app.use(cors({
  origin: function(origin, callback) {
    if (ALLOWED_ORIGINS.includes(origin)) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}))

Cause 2: Auth0 domain not in allowed origins

Solution 2 (Auth0 Dashboard):

Auth0 Dashboard → Applications → Settings

Allowed Web Origins:
http://localhost:3000    (for development)
https://myapp.com        (for production)

(Allows Auth0 calls from these origins)

Cause 3: Missing credentials in request

Solution 3:

// Make sure credentials are included
fetch('/api/items', {
  headers: { Authorization: `Bearer ${token}` },
  credentials: 'include'  // Important for cookies
})

Test:

# Test CORS
curl -H "Origin: http://localhost:3000" \
  -H "Access-Control-Request-Method: GET" \
  http://localhost:3001/api/items

# Should include Access-Control-Allow-Origin header

Issue: Silent Authentication Fails

Error: Silent auth not working, user must login again

Cause 1: Cache location wrong

Solution 1:

// WRONG ❌
new Auth0Provider({
  cacheLocation: 'localStorage'  // Can't do silent auth in localStorage
})

// RIGHT ✅
new Auth0Provider({
  cacheLocation: 'memory'  // For SPAs
})

Cause 2: Refresh token not rotated

Solution 2:

Auth0 Dashboard → Applications → Settings

Refresh Token Rotation: Enabled ✅
Refresh Token Expiration Absolute: 2592000 (30 days)

Cause 3: Third-party cookies blocked

Solution 3 (for local development):

Browser → Settings → Privacy → Cookies
Allow cookies (at least for localhost)

Test:

// Test silent auth
async function testSilentAuth() {
  const token = await getAccessTokenSilently()
  console.log('Silent auth worked:', token)
}

Issue: Scope Not in Token

Error: Token doesn't include required scope

Cause 1: Scope not requested during login

Solution 1:

// WRONG ❌
Auth0Provider({
  // No scope specified
})

// RIGHT ✅
Auth0Provider({
  authorizationParams: {
    scope: 'openid profile email read:items write:items'
  }
})

Cause 2: Scope not configured in Auth0

Solution 2:

Auth0 Dashboard → APIs → Your API → Scopes

Add:
+ read:items (Read access)
+ write:items (Write access)
+ delete:items (Delete access)

Cause 3: User not consented to scope

Solution 3:

Auth0 Dashboard → Connections → Settings

Require consent: Off (for internal apps)
Or allow user to accept scopes during login

Test:

// Decode token to check scopes
const decoded = jwt_decode(token)
console.log('Scopes:', decoded.scope)

Issue: MFA Login Failing

Error: "MFA is required" but MFA setup failed

Cause 1: MFA not configured

Solution 1:

Auth0 Dashboard → Connections → Authenticators

Enable:
✓ Google Authenticator
✓ SMS (optional)
✓ Email OTP

Require MFA: Off/On (depending on policy)

Cause 2: User hasn't set up MFA method

Solution 2:

Users must register MFA before login:
1. First login (without MFA)
2. Prompted to set up authenticator
3. Scan QR code or enter backup codes
4. Subsequent logins require MFA

Cause 3: Recovery codes not working

Solution 3:

If user loses authenticator:
1. User clicks "Can't scan?"
2. Gets backup codes
3. Use one code to login
4. Setup new authenticator

Or admin can reset MFA:
Auth0 Dashboard → Users → Select user → Actions → Reset authenticators

Test:

# Test MFA flow
# 1. Enable MFA in Auth0
# 2. Create test user
# 3. Login → should prompt for authenticator setup

Issue: Logout Not Clearing Session

Error: User clicks logout but remains logged in

Cause 1: Wrong logout URL

Solution 1 (React):

// WRONG ❌
logout()  // Doesn't redirect or clear Auth0 session

// RIGHT ✅
logout({
  logoutParams: {
    returnTo: window.location.origin  // Redirect after logout
  }
})

Cause 2: Logout URL not in Auth0 allowlist

Solution 2:

Auth0 Dashboard → Applications → Settings

Allowed Logout URLs:
http://localhost:3000
https://myapp.com

(Must match where user is redirected after logout)

Cause 3: Session still active server-side

Solution 3 (Next.js):

// API route for logout
export default async function handler(req, res) {
  await clearSession(res)  // Auth0 SDK clears session
  res.redirect('/')
}

// Or explicitly
import { getSession } from '@auth0/nextjs-auth0'

export const GET = async (req) => {
  const session = await getSession()
  if (session) {
    await logout(req)  // Clears Auth0 session
  }
}

Test:

# Test logout
# 1. Login successfully
# 2. Click logout
# 3. Check:
#    - Redirected to home
#    - Cookies cleared
#    - New login required

Issue: Social Login Not Working

Error: Social login button doesn't work or redirects to error

Cause 1: Social connection not enabled for app

Solution 1:

Auth0 Dashboard → Connections → Social → Google

Under "Select Applications":
Toggle: Your App → Enable ✅

(Same for Facebook, GitHub, etc.)

Cause 2: Social app credentials wrong

Solution 2 (Google example):

Auth0 Dashboard → Connections → Social → Google

Google OAuth2 settings:
Client ID: __________ (from Google Cloud Console)
Client Secret: __________ (from Google Cloud Console)

Get credentials:
1. Google Cloud Console: https://console.cloud.google.com
2. Create new project
3. Enable Google+ API
4. Create OAuth 2.0 Client ID
5. Copy Client ID and Secret to Auth0

Cause 3: Redirect URI not configured in social app

Solution 3:

Google Cloud Console:
Authorized redirect URIs:
https://YOUR_DOMAIN/login/callback

Facebook App Settings:
Valid OAuth Redirect URIs:
https://YOUR_DOMAIN/login/callback

GitHub:
Authorization callback URL:
https://YOUR_DOMAIN/login/callback

Test:

# Test social login
# 1. Visit login page
# 2. Click "Login with Google"
# 3. Should redirect to Google
# 4. After signin, should return to app

General Debugging Techniques

1. Check Auth0 Logs

Auth0 Dashboard → Logs

Shows all auth events with:
- User email
- Event type (login, logout, error)
- Timestamp
- Error details

2. Inspect Token

// In browser console
const token = await auth0.getAccessTokenSilently()

// Decode at jwt.io
// Or programmatically
import jwt_decode from 'jwt-decode'
const decoded = jwt_decode(token)
console.log(decoded)

3. Check Request Headers

# In browser DevTools → Network tab
# Select API request
# Check headers:
#   Authorization: Bearer {token}
#   Content-Type: application/json

4. Enable Debug Mode

// React
<Auth0Provider
  domain={domain}
  clientId={clientId}
  logoutParams={{ returnTo: 'http://localhost:3000' }}
  onError={(error) => console.error('Auth0 Error:', error)}
>

Still Having Issues?

  1. Check Auth0 Logs: Auth0 Dashboard → Logs (shows actual errors)
  2. Run security audit: /oauth-security-audit
  3. Review implementation: /oauth-implement [framework]
  4. Check Auth0 docs: https://auth0.com/docs
  5. Contact support: https://support.auth0.com

Status: Troubleshooting guide ready!