Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:04:20 +08:00
commit 30a2216ea3
12 changed files with 4981 additions and 0 deletions

417
commands/oauth-implement.md Normal file
View File

@@ -0,0 +1,417 @@
---
description: Framework-specific implementation guide for adding Auth0 OAuth to your application
---
# OAuth Implementation Guide
Detailed code walkthrough for implementing Auth0 authentication in your framework.
## Quick Start
```bash
/oauth-implement [framework]
```
Supported frameworks:
- `react` - React with Create React App or Vite
- `nextjs` - Next.js (13+ with App Router recommended)
- `nodejs` - Node.js/Express backend
- `fastapi` - Python FastAPI
- `django` - Python Django
- `vue` - Vue.js
- `svelte` - Svelte
- `flutter` - Flutter mobile
- `react-native` - React Native mobile
## Implementation Steps by Framework
### React (SPA)
#### 1. Install Auth0 React SDK
```bash
npm install @auth0/auth0-react
```
#### 2. Wrap App with Auth0Provider
```typescript
// src/main.tsx
import { Auth0Provider } from '@auth0/auth0-react'
ReactDOM.createRoot(document.getElementById('root')!).render(
<Auth0Provider
domain={import.meta.env.VITE_AUTH0_DOMAIN}
clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}
authorizationParams={{
redirect_uri: window.location.origin,
scope: 'openid profile email read:items',
audience: `https://${import.meta.env.VITE_AUTH0_DOMAIN}/api/v2/`
}}
cacheLocation="memory"
>
<App />
</Auth0Provider>
)
```
#### 3. Create Login/Logout Components
```typescript
// src/components/Auth.tsx
import { useAuth0 } from '@auth0/auth0-react'
export function LoginButton() {
const { loginWithRedirect, isAuthenticated } = useAuth0()
if (isAuthenticated) return null
return <button onClick={() => loginWithRedirect()}>Login</button>
}
export function LogoutButton() {
const { logout, isAuthenticated } = useAuth0()
if (!isAuthenticated) return null
return <button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>Logout</button>
}
export function Profile() {
const { user, isAuthenticated } = useAuth0()
if (!isAuthenticated) return <p>Not logged in</p>
return (
<div>
<img src={user?.picture} alt={user?.name} />
<h2>{user?.name}</h2>
<p>{user?.email}</p>
</div>
)
}
```
#### 4. Protected Routes
```typescript
// src/components/ProtectedRoute.tsx
import { useAuth0 } from '@auth0/auth0-react'
export function ProtectedRoute({ children }: any) {
const { isAuthenticated, isLoading } = useAuth0()
if (isLoading) return <div>Loading...</div>
if (!isAuthenticated) return <div>Please log in</div>
return children
}
// In App.tsx
<Routes>
<Route path="/dashboard" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
</Routes>
```
#### 5. Call Protected API
```typescript
// src/hooks/useApi.ts
import { useAuth0 } from '@auth0/auth0-react'
import { useEffect, useState } from 'react'
export function useApi<T>(url: string) {
const { getAccessTokenSilently } = useAuth0()
const [data, setData] = useState<T | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<Error | null>(null)
useEffect(() => {
let isMounted = true
const fetchData = async () => {
try {
const token = await getAccessTokenSilently()
const response = await fetch(url, {
headers: { Authorization: `Bearer ${token}` }
})
if (!response.ok) throw new Error('API error')
const result = await response.json()
if (isMounted) setData(result)
} catch (err) {
if (isMounted) setError(err instanceof Error ? err : new Error('Unknown error'))
} finally {
if (isMounted) setLoading(false)
}
}
fetchData()
return () => { isMounted = false }
}, [url, getAccessTokenSilently])
return { data, error, loading }
}
```
#### 6. Environment Variables
```env
VITE_AUTH0_DOMAIN=YOUR_DOMAIN.auth0.com
VITE_AUTH0_CLIENT_ID=YOUR_CLIENT_ID
```
---
### Next.js (Full-Stack)
#### 1. Install SDK
```bash
npm install @auth0/nextjs-auth0
```
#### 2. Create Auth Routes
**App Router** (Recommended):
```typescript
// app/api/auth/[auth0]/route.ts
import { handleAuth } from '@auth0/nextjs-auth0'
export const GET = handleAuth()
```
**Pages Router**:
```typescript
// pages/api/auth/[auth0].ts
import { handleAuth } from '@auth0/nextjs-auth0'
export default handleAuth()
```
#### 3. Access User in Components
**App Router**:
```typescript
// app/profile/page.tsx
import { getSession } from '@auth0/nextjs-auth0'
import { redirect } from 'next/navigation'
export default async function ProfilePage() {
const session = await getSession()
if (!session) {
redirect('/api/auth/login')
}
return (
<div>
<h1>Welcome, {session.user.name}</h1>
<img src={session.user.picture} alt={session.user.name} />
</div>
)
}
```
#### 4. Login/Logout Links
```typescript
// app/components/Nav.tsx
import { getSession } from '@auth0/nextjs-auth0'
export async function Nav() {
const session = await getSession()
return (
<nav>
{session ? (
<>
<span>{session.user.name}</span>
<a href="/api/auth/logout">Logout</a>
</>
) : (
<a href="/api/auth/login">Login</a>
)}
</nav>
)
}
```
#### 5. Call API with Token
```typescript
// app/api/items/route.ts
import { getSession } from '@auth0/nextjs-auth0'
import { NextResponse } from 'next/server'
export async function GET() {
const session = await getSession()
if (!session) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const response = await fetch('http://localhost:3001/items', {
headers: { Authorization: `Bearer ${session.accessToken}` }
})
return NextResponse.json(await response.json())
}
```
#### 6. Environment Variables
```env
AUTH0_SECRET='[generated secret]'
AUTH0_BASE_URL='http://localhost:3000'
AUTH0_ISSUER_BASE_URL='https://YOUR_DOMAIN.auth0.com'
AUTH0_CLIENT_ID='YOUR_CLIENT_ID'
AUTH0_CLIENT_SECRET='YOUR_CLIENT_SECRET'
```
---
### Node.js/Express Backend
#### 1. Install Dependencies
```bash
npm install express-jwt jwks-rsa
```
#### 2. Create JWT Middleware
```typescript
// middleware/auth.ts
import { expressjwt as jwt } from 'express-jwt'
import jwksRsa from 'jwks-rsa'
const checkJwt = jwt({
secret: jwksRsa.expressJwtSecret({
cache: true,
jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
}),
audience: `https://${process.env.AUTH0_DOMAIN}/api/v2/`,
issuer: `https://${process.env.AUTH0_DOMAIN}/`,
algorithms: ['RS256']
})
export default checkJwt
```
#### 3. Protect Routes
```typescript
// routes/items.ts
import express from 'express'
import checkJwt from '../middleware/auth'
const router = express.Router()
router.get('/public', (req, res) => {
res.json({ message: 'Public' })
})
router.get('/items', checkJwt, (req, res) => {
// req.auth contains decoded JWT
res.json({ userId: req.auth.sub, items: [] })
})
// Scope validation
router.delete('/items/:id', checkJwt, (req, res) => {
const scope = req.auth.scope?.split(' ') || []
if (!scope.includes('delete:items')) {
return res.status(403).json({ error: 'Insufficient permissions' })
}
res.json({ message: 'Item deleted' })
})
export default router
```
---
### FastAPI (Python)
```python
# main.py
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthCredentials
import jwt
from jwt import algorithms
app = FastAPI()
security = HTTPBearer()
DOMAIN = "YOUR_DOMAIN.auth0.com"
async def verify_token(credentials: HTTPAuthCredentials = Depends(security)):
token = credentials.credentials
try:
# Get public key
jwks_client = jwt.PyJWKClient(f"https://{DOMAIN}/.well-known/jwks.json")
signing_key = jwks_client.get_signing_key_from_jwt(token)
# Verify token
payload = jwt.decode(
token,
signing_key.key,
algorithms=["RS256"],
audience=f"https://{DOMAIN}/api/v2/",
issuer=f"https://{DOMAIN}/"
)
return payload
except Exception as e:
raise HTTPException(status_code=401, detail="Invalid token")
@app.get("/items")
async def get_items(user: dict = Depends(verify_token)):
return { "user_id": user["sub"], "items": [] }
```
---
## Testing Implementation
### Test Login Flow
```bash
# 1. Visit login page
open http://localhost:3000/api/auth/login
# 2. Complete auth flow in Auth0
# 3. Check if callback works
# 4. Test API
curl -H "Authorization: Bearer <ACCESS_TOKEN>" \
http://localhost:3001/api/items
```
### Inspect Token (React)
```javascript
// In browser console
const token = await auth0.getAccessTokenSilently()
console.log(token)
// Decode at jwt.io
```
---
## Common Issues & Solutions
| Issue | Solution |
|-------|----------|
| Token expired | SDK auto-refreshes, check refresh token rotation enabled |
| CORS error | Configure CORS in backend, check Auth0 allowed origins |
| Silent auth fails | Check `cacheLocation: "memory"`, try explicit login |
| Scope not in token | Add to Auth0 rule or API scopes config |
| Token validation fails | Verify audience, issuer, algorithms match |
---
## Next Steps
1. Test implementation with `/oauth-security-audit`
2. Run `/oauth-troubleshoot` for any issues
3. Deploy and update callback URLs to production domain
**Status**: Implementation guide ready!

417
commands/oauth-migrate.md Normal file
View File

@@ -0,0 +1,417 @@
---
description: Migration guide for moving from other auth providers to Auth0
---
# OAuth Migration Guide
Migrate from other authentication providers to Auth0.
## Quick Start
```bash
/oauth-migrate [provider]
```
Supported providers:
- `firebase` - Firebase Authentication
- `okta` - Okta
- `cognito` - AWS Cognito
- `keycloak` - Keycloak
- `custom` - Custom JWT/OAuth implementation
- `social-only` - Only social logins (no user DB)
---
## Migration: Firebase → Auth0
### Phase 1: Planning (1-2 hours)
**Assess current setup**:
- How many users? (1k, 100k, 1M+)
- Authentication methods? (email/password, social, custom)
- Custom claims? (roles, metadata)
- Token usage? (access tokens, ID tokens)
**Timeline**:
- Small (1k users): 1 day
- Medium (10k users): 3-5 days
- Large (100k+ users): 1-2 weeks
**Parallel running** (recommended):
- Keep Firebase running while testing Auth0
- Gradual migration: 10% → 25% → 50% → 100%
- Rollback plan: If Auth0 issues, fall back to Firebase
---
### Phase 2: Set Up Auth0 (1-2 hours)
```bash
# Step 1: Create Auth0 account
# https://auth0.com/signup
# Step 2: Create application
/oauth-setup-auth0
# Step 3: Configure connections
# - Enable database connection
# - Enable same social connections as Firebase
# - Copy social app credentials from Firebase
```
---
### Phase 3: User Migration (1-3 days)
#### Option A: Automatic Migration (Recommended)
Use Auth0 extensibility to migrate users on first login:
```javascript
// Auth0 Rule: Migrate users from Firebase
module.exports = function(user, context, callback) {
// Check if user already in Auth0
if (user.identities && user.identities.length > 0) {
return callback(null, user, context)
}
// Try to authenticate against Firebase
const firebase = require('firebase')
firebase.initializeApp({
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.FIREBASE_DATABASE_URL
})
firebase.auth().signInWithEmailAndPassword(user.email, context.request.query.password)
.then(function(firebaseUser) {
// Get Firebase custom claims
firebaseUser.getIdTokenResult()
.then(function(idTokenResult) {
// Copy Firebase claims to Auth0
user.app_metadata = user.app_metadata || {}
user.app_metadata.firebase_id = firebaseUser.uid
user.app_metadata.roles = idTokenResult.claims.roles || []
// Create Auth0 user
context.clientMetadata = {
firebase_migrated: 'true'
}
callback(null, user, context)
})
})
.catch(function(error) {
callback(new Error('Firebase auth failed: ' + error.message))
})
}
```
**Benefits**:
- ✅ No downtime
- ✅ Users migrate automatically on first login
- ✅ Can run parallel with Firebase
- ✅ Easy rollback
**Timeline**: 2-3 weeks (let users naturally migrate)
---
#### Option B: Bulk Migration
Export Firebase users and import to Auth0:
```bash
# Step 1: Export users from Firebase
firebase auth:export users.json --format json
# Step 2: Transform to Auth0 format
node transform-firebase-to-auth0.js
# Step 3: Import to Auth0
# Auth0 Dashboard → Users → Import (drag CSV)
# Or use Management API
```
**transform-firebase-to-auth0.js**:
```javascript
const fs = require('fs')
const firebaseUsers = JSON.parse(fs.readFileSync('users.json', 'utf8'))
const auth0Users = firebaseUsers.users.map(user => ({
email: user.email,
email_verified: user.emailVerified,
user_id: user.localId,
identities: [{
connection: 'Username-Password-Authentication',
user_id: user.localId,
provider: 'auth0',
isSocial: false
}],
user_metadata: user.customClaims || {},
app_metadata: {
roles: user.customClaims?.roles || [],
firebase_id: user.localId
},
blocked: !user.emailVerified,
created_at: new Date(parseInt(user.createdAt)).toISOString(),
updated_at: new Date(parseInt(user.lastLoginAt)).toISOString()
}))
fs.writeFileSync('auth0-users.json', JSON.stringify(auth0Users, null, 2))
console.log(`Converted ${auth0Users.length} users`)
```
**Timeline**: 1-2 hours (bulk import) + verification
---
### Phase 4: Update Application Code (2-4 hours)
#### Frontend Migration (React)
```typescript
// BEFORE (Firebase)
import { initializeApp } from 'firebase/app'
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'
const app = initializeApp(firebaseConfig)
const auth = getAuth(app)
async function login(email, password) {
const userCredential = await signInWithEmailAndPassword(auth, email, password)
const token = await userCredential.user.getIdToken()
return token
}
// AFTER (Auth0)
import { useAuth0 } from '@auth0/auth0-react'
function LoginPage() {
const { loginWithRedirect } = useAuth0()
return (
<button onClick={() => loginWithRedirect()}>
Login with Auth0
</button>
)
}
export default function App() {
const { getAccessTokenSilently } = useAuth0()
async function getToken() {
return await getAccessTokenSilently()
}
}
```
#### Backend Migration (Node.js)
```typescript
// BEFORE (Firebase)
import * as admin from 'firebase-admin'
const app = admin.initializeApp()
function verifyToken(token) {
return admin.auth().verifyIdToken(token)
}
// AFTER (Auth0)
import { expressjwt } from 'express-jwt'
import jwksRsa from 'jwks-rsa'
const checkJwt = expressjwt({
secret: jwksRsa.expressJwtSecret({
jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
}),
audience: `https://${process.env.AUTH0_DOMAIN}/api/v2/`,
issuer: `https://${process.env.AUTH0_DOMAIN}/`,
algorithms: ['RS256']
})
app.get('/api/protected', checkJwt, (req, res) => {
res.json({ user: req.auth.sub })
})
```
---
### Phase 5: Testing (1-2 days)
```typescript
// Test list
- [ ] User login (email/password)
- [ ] User signup
- [ ] Social login (Google, GitHub, etc)
- [ ] Password reset
- [ ] Token refresh
- [ ] API access with token
- [ ] MFA (if enabled)
- [ ] Logout clears session
- [ ] Session persistence
- [ ] Error handling (invalid password, etc)
```
**Test script**:
```bash
# Test login flow
curl -X POST https://YOUR_DOMAIN/oauth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"audience": "https://YOUR_DOMAIN/api/v2/",
"grant_type": "client_credentials"
}'
# Test protected API
curl -H "Authorization: Bearer ACCESS_TOKEN" \
http://localhost:3001/api/protected
```
---
### Phase 6: Deployment (2-4 hours)
**Deployment checklist**:
- [ ] Update environment variables
- [ ] Deploy frontend to staging
- [ ] Deploy backend to staging
- [ ] Run full test suite
- [ ] Smoke test in production-like environment
- [ ] Deploy to production
- [ ] Monitor Auth0 logs for errors
- [ ] Monitor application errors
- [ ] Have rollback plan ready
**Gradual rollout**:
1. Deploy to 10% of users
2. Monitor for 2-4 hours
3. If OK, deploy to 50%
4. Monitor for 2-4 hours
5. Deploy to 100%
---
## Migration: Cognito → Auth0
### Key Differences
| Feature | Cognito | Auth0 |
|---------|---------|-------|
| Setup | AWS Dashboard (complex) | Auth0 Dashboard (simple) |
| Scopes | Fixed scopes | Custom scopes |
| Rules | Limited | Powerful (JavaScript) |
| User management | Via AWS API | Via UI or API |
| Custom claims | userAttributes | app_metadata, user_metadata |
| MFA | Built-in | Multiple options |
| Cost | Pay per user | Fixed tier |
### Migration Steps
1. **Export Cognito users**:
```bash
aws cognito-idp list-users --user-pool-id us-east-1_xxx > cognito-users.json
```
2. **Transform to Auth0 format**:
```javascript
// Similar to Firebase migration
// Map Cognito attributes to Auth0 metadata
```
3. **Update token validation**:
```typescript
// Change from Cognito to Auth0 jwks URI
jwksUri: `https://${AUTH0_DOMAIN}/.well-known/jwks.json`
```
4. **Update frontend SDK**:
```typescript
// Replace Amplify with Auth0 SDK
import { useAuth0 } from '@auth0/auth0-react'
```
---
## Rollback Plan
### If issues occur:
1. **Immediately revert** to previous provider
2. **Keep both systems running** during migration
3. **Have database backup** before migration
4. **Monitor error rates** during rollout
```bash
# Revert frontend
git revert <commit> # Go back to old SDK
npm install # Reinstall old packages
npm run deploy # Deploy rollback
# Check status
Auth0 Dashboard → Logs (verify no new logins via Auth0)
Firebase Console → Logs (verify resumed usage)
```
---
## Post-Migration
### Cleanup
- [ ] Decommission old auth system
- [ ] Delete old user data (after retention period)
- [ ] Update documentation
- [ ] Train team on new system
- [ ] Close old auth provider account
### Optimization
- [ ] Review Auth0 rules for performance
- [ ] Optimize token expiration
- [ ] Set up audit logging
- [ ] Monitor costs
- [ ] Plan security hardening
---
## Common Migration Issues
| Issue | Solution |
|-------|----------|
| User exists error on import | Deduplicate by email before import |
| Scopes missing | Manually add to Auth0 API config |
| Custom claims lost | Map to user_metadata in Auth0 |
| Password reset broken | Reconfigure email templates in Auth0 |
| Social login not working | Re-add social app credentials |
---
## Timeline Summary
| Provider | Automatic | Bulk | Total |
|----------|-----------|------|-------|
| Firebase (1k users) | 2-3 weeks | 3-5 days | 1 week |
| Firebase (100k users) | 3-4 weeks | 2-3 weeks | 4-5 weeks |
| Cognito (any size) | 2-3 weeks | Similar to Firebase | 3-5 weeks |
| Custom OAuth (simple) | 1 week | 2-3 days | 1 week |
| Custom OAuth (complex) | 2-3 weeks | 1-2 weeks | 3-4 weeks |
---
## Next Steps
1. **Choose migration strategy** (automatic vs bulk)
2. **Set up Auth0 tenant** (`/oauth-setup-auth0`)
3. **Test integration** (`/oauth-implement [framework]`)
4. **Run security audit** (`/oauth-security-audit`)
5. **Execute migration** (follow phase-by-phase plan)
6. **Monitor closely** during first week
---
**Status**: Migration guide ready!
**Need help?** `/oauth-troubleshoot` or contact Auth0 support

View File

@@ -0,0 +1,303 @@
---
description: Security audit checklist for Auth0 OAuth implementation
---
# OAuth Security Audit
Run a comprehensive security audit on your Auth0 implementation.
## Quick Start
```bash
/oauth-security-audit
```
This will check:
- Token security (storage, expiration, rotation)
- OAuth flow security (PKCE, state parameter, CSRF)
- Compliance (GDPR, HIPAA, SOC2)
- Configuration hardening
- Common vulnerabilities
---
## Security Checklist
### Frontend Security
- [ ] **Token Storage**: In-memory or HTTP-only cookies only (NO localStorage)
- Check: `grep -r "localStorage.*token" src/`
- Should be empty
- [ ] **PKCE Enabled**: For SPAs (Authorization Code + PKCE)
- Check: Auth0 React SDK handles automatically ✅
- Or verify custom code includes `code_verifier`
- [ ] **State Parameter**: CSRF protection
- Check: Auth0 SDKs handle automatically ✅
- Or verify `state` parameter in custom auth flow
- [ ] **HTTPS Enforced**: All auth requests over HTTPS
- Check: No `http://` in production callback URLs
- Production callback URLs use `https://`
- [ ] **Token Expiration Short**: Access tokens < 15 minutes
- Check: Auth0 Dashboard → Applications → Settings → Token Expiration
- Should be: 300-900 seconds (5-15 minutes)
- [ ] **Refresh Token Rotation**: Enabled for token refresh
- Check: Auth0 Dashboard → Applications → Settings → Refresh Token Rotation
- Should be: Enabled ✅
- [ ] **Content Security Policy (CSP)**: Restrict script sources
- Check: HTTP header `Content-Security-Policy`
- Should include: `default-src 'self'`
---
### Backend Security
- [ ] **JWT Signature Validation**: Verify token signature
- Check: Code uses `jwt.verify()` with public key
- Should NOT use: `jwt.decode()` (no verification)
- [ ] **Audience Validation**: Check `aud` claim matches API
- Check: `jwt.verify(token, key, { audience: 'https://api.example.com' })`
- Token `aud` must match expected audience
- [ ] **Issuer Validation**: Check `iss` claim matches Auth0 domain
- Check: `jwt.verify(token, key, { issuer: 'https://YOUR_DOMAIN/' })`
- Token `iss` must match Auth0 domain
- [ ] **Algorithm Validation**: Only RS256 (asymmetric)
- Check: `jwt.verify(token, key, { algorithms: ['RS256'] })`
- Should NOT allow: `HS256` (symmetric, security risk)
- [ ] **Scope Validation**: Check scopes for authorization
- Check: Code validates `token.scope` includes required scope
- Example: `if (!scopes.includes('delete:items')) return 403`
- [ ] **No Token in Logs**: Sensitive tokens not logged
- Check: `grep -r "token\|password\|secret" logs/`
- Should be: Sanitized or empty
- [ ] **CORS Configured Properly**: Only allow trusted origins
- Check: `app.use(cors({ origin: ['https://myapp.com'] }))`
- Should NOT be: `origin: '*'` (allows any origin)
---
### Auth0 Configuration Security
- [ ] **MFA Enabled**: Multi-factor authentication required
- Check: Auth0 Dashboard → Connections → Authenticators
- Should have: Google Authenticator, SMS, or Email OTP enabled
- [ ] **Password Policy**: Strong passwords required
- Check: Auth0 Dashboard → Connections → Database → Password Policy
- Should be: "Good" or "Excellent"
- [ ] **Suspicious Activity Detection**: Enabled
- Check: Auth0 Dashboard → Security → Attack Protection
- Should have: Brute force, suspicious IP protection enabled
- [ ] **Logout Clears Session**: User properly logged out
- Check: `/api/auth/logout` clears all session data
- Should have: `logoutParams: { returnTo: safe_url }`
- [ ] **No Overpermissioned Scopes**: Only request necessary scopes
- Check: Auth0 Dashboard → Applications → Settings → Default Audience
- Should be: Minimal (e.g., `openid profile email`)
- [ ] **API Keys Secure**: Secrets not in version control
- Check: `.env` is in `.gitignore`
- Should NOT be in: `git log`, `public files`, `comments`
- [ ] **Rules/Actions Audited**: Custom logic secure
- Check: Auth0 Dashboard → Rules → [Review each rule]
- Should NOT: Grant extra permissions, log passwords, call untrusted APIs
---
### Data Protection & Compliance
- [ ] **GDPR Compliant**: User consent, deletion, portability
- [ ] Consent shown before social login
- [ ] User can request data deletion (via API or form)
- [ ] Data deletion implemented (removes from Auth0 + your DB)
- [ ] Privacy policy links from login page
- [ ] **HIPAA Compliant**: (if handling health data)
- [ ] Business Associate Agreement (BAA) signed with Auth0
- [ ] MFA enforced
- [ ] Audit logging enabled
- [ ] Data encrypted in transit (HTTPS) and at rest
- [ ] **SOC2 Compliant**: If required for compliance
- [ ] Change logs available (Auth0 Logs)
- [ ] Access controls documented
- [ ] Incident response plan in place
- [ ] Regular security assessments done
- [ ] **Data Residency**: Data stored in correct region
- Check: Auth0 Dashboard → Tenants → Region
- EU apps: Select "Europe" region
- US apps: Select "United States" region
---
### Error Handling & Logging
- [ ] **Errors Don't Leak Info**: Auth errors are generic
- Check: Error messages in UI
- Should be: "Login failed" (NOT "Email doesn't exist" or "Invalid password")
- [ ] **Webhook Errors Handled**: Failures don't break auth flow
- Check: Webhook error handler has try/catch
- Should have: Retry logic with exponential backoff
- [ ] **Audit Logs Enabled**: All auth events logged
- Check: Auth0 Dashboard → Logs (shows all login events)
- Should have: 100+ entries with timestamps
- [ ] **Sensitive Data Redacted**: Logs don't contain secrets
- Check: grep -r "password\|token\|secret" logs/
- Should be: Redacted or not logged
---
### Testing
- [ ] **Unit Tests**: Auth components tested
- Check: `npm test` includes auth tests
- Should have: Mock Auth0, test protected routes
- [ ] **Integration Tests**: Auth flow tested end-to-end
- Check: Test login → callback → API call
- Should verify: Token exchange, API access
- [ ] **Security Tests**: Vulnerabilities tested
- [ ] Test expired token handling
- [ ] Test invalid token rejection
- [ ] Test missing scope error (403)
- [ ] Test logout clears session
---
## Security Scoring
**Count your checkmarks**:
- 40+ checked: ✅ **Excellent** (Production ready)
- 30-39 checked: ⚠️ **Good** (Address medium priority items)
- 20-29 checked: ❌ **Fair** (Address high priority items)
- <20 checked: 🚨 **Critical** (Major issues, don't deploy)
---
## Common Vulnerabilities to Fix
### 1. Token Leakage (Critical)
```javascript
// WRONG ❌
localStorage.setItem('token', accessToken)
sessionStorage.setItem('token', accessToken)
// RIGHT ✅
// Use Auth0 SDK (in-memory storage)
// Or for Next.js (HTTP-only cookies)
```
### 2. Missing PKCE (High)
```javascript
// WRONG ❌
// No code_verifier or code_challenge
// RIGHT ✅
// Use Auth0 React SDK (automatic PKCE)
// Or custom: include code_verifier in token exchange
```
### 3. Wrong Token Type (High)
```javascript
// WRONG ❌
const idToken = getIDToken()
fetch('/api/items', {
headers: { Authorization: `Bearer ${idToken}` }
})
// RIGHT ✅
const accessToken = getAccessToken()
fetch('/api/items', {
headers: { Authorization: `Bearer ${accessToken}` }
})
```
### 4. No Audience Validation (High)
```typescript
// WRONG ❌
jwt.verify(token, publicKey) // No audience check
// RIGHT ✅
jwt.verify(token, publicKey, {
audience: 'https://api.myapp.com'
})
```
### 5. Scope Not Checked (Medium)
```typescript
// WRONG ❌
app.delete('/items/:id', checkJwt, (req, res) => {
// Delete without scope check
res.json({ deleted: true })
})
// RIGHT ✅
app.delete('/items/:id', checkJwt, (req, res) => {
const scopes = req.auth.scope?.split(' ') || []
if (!scopes.includes('delete:items')) {
return res.status(403).json({ error: 'Insufficient permissions' })
}
res.json({ deleted: true })
})
```
---
## Remediation Priority
### Priority 1 (Fix immediately - before production)
- [ ] Token storage (localStorage → in-memory)
- [ ] JWT signature validation
- [ ] Audience validation
- [ ] HTTPS enforced
### Priority 2 (Fix within 1 week)
- [ ] Scope validation in API
- [ ] MFA enabled
- [ ] Audit logging
- [ ] CSRF protection (state parameter)
### Priority 3 (Fix within 1 month)
- [ ] Compliance (GDPR, HIPAA)
- [ ] Webhook error handling
- [ ] Security testing
- [ ] Incident response plan
---
## Next Steps
1. **Review this checklist** with your team
2. **Fix high-priority items** (Priority 1)
3. **Run again**: `/oauth-security-audit`
4. **If issues remain**: `/oauth-troubleshoot` for help
---
**Score**: [X] / 45 items checked

View File

@@ -0,0 +1,452 @@
---
description: Interactive Auth0 setup wizard for configuring OAuth applications, connections, and tenant settings
---
# Auth0 OAuth Setup Wizard
Interactive guided setup for Auth0 authentication from scratch.
## Quick Start
```bash
/oauth-setup-auth0
```
This will walk you through:
1. **Auth0 Tenant Creation** - Create new Auth0 account/tenant
2. **Application Configuration** - Set up app (SPA, Web, Mobile, M2M)
3. **Connection Setup** - Configure database, social, enterprise login
4. **Callback URL Configuration** - Set up redirect URIs
5. **Basic Security** - Enable MFA, set token expiration
6. **Environment Variables** - Generate .env file template
## Step-by-Step Wizard
### Step 1: Auth0 Tenant Setup
If you don't have an Auth0 account:
1. **Visit**: https://auth0.com/signup
2. **Create account** with:
- Email: Your business email
- Password: Strong password
- Company: Your company name
3. **Choose region**: US, EU, or AU
4. **Create tenant** - Auth0 generates unique domain:
- Example: `mycompany.auth0.com`
**What you'll get**:
- Auth0 Dashboard access
- Domain: `YOUR_DOMAIN.auth0.com`
- Client ID & Secret for dashboard
---
### Step 2: Select Application Type
**Choose based on your tech stack**:
#### Option 1: Single Page Application (SPA)
**For**: React, Vue, Angular, Svelte, Next.js (client-side)
**Characteristics**:
- Code runs in browser
- Public client (no secret needed)
- OAuth Flow: Authorization Code + PKCE
- Token Storage: In-memory (secure)
**Setup**:
```
Auth0 Dashboard → Applications → Create Application
Name: My React App
Type: Single Page Application
Settings:
- Allowed Callback URLs: http://localhost:3000/callback
- Allowed Logout URLs: http://localhost:3000
- Allowed Web Origins: http://localhost:3000
- Token Endpoint Authentication: None
```
#### Option 2: Web Application (Server-Side)
**For**: Next.js, Express, Django, Rails (with server)
**Characteristics**:
- Code runs on server
- Confidential client (has secret)
- OAuth Flow: Authorization Code (no PKCE needed)
- Token Storage: HTTP-only cookies
**Setup**:
```
Auth0 Dashboard → Applications → Create Application
Name: My Next.js App
Type: Regular Web Applications
Settings:
- Allowed Callback URLs: http://localhost:3000/api/auth/callback
- Allowed Logout URLs: http://localhost:3000
- Token Endpoint Authentication: Post
- Secret: [Auto-generated, copy to .env]
```
#### Option 3: Machine-to-Machine (M2M)
**For**: Backend services, scheduled jobs, CLI tools
**Characteristics**:
- No user interaction
- Confidential client
- OAuth Flow: Client Credentials
- Use Case: Calling Auth0 Management API
**Setup**:
```
Auth0 Dashboard → Applications → Create Application
Name: My Backend Service
Type: Machine-to-Machine Applications
Settings:
- Grant Types: client_credentials
- Audience: https://YOUR_DOMAIN/api/v2/
- Secret: [Auto-generated, copy to .env]
```
#### Option 4: Native Application
**For**: iOS, Android, React Native apps
**Characteristics**:
- Runs on device
- Public client (no secret)
- OAuth Flow: Authorization Code + PKCE
- Callback: Custom URL scheme or App Link
**Setup**:
```
Auth0 Dashboard → Applications → Create Application
Name: My Mobile App
Type: Native
Settings:
- Allowed Callback URLs: com.myapp://callback
- Allowed Logout URLs: com.myapp://logout
- Token Endpoint Authentication: None
```
---
### Step 3: Configure Connections
Choose how users authenticate:
#### Option 1: Username/Password Database
**Built-in Auth0 database**
**Enable**:
```
Auth0 Dashboard → Connections → Database → Username-Password-Authentication
Settings:
- Allow Signup: Yes (if you want user self-registration)
- Require Email Verification: Yes
- Password Policy: Good (mixed case, numbers, symbols)
- Disable signup for: [Your application]
```
**Usage**:
```
Users can sign up at: YOUR_DOMAIN/signup
Or you create users via API
```
---
#### Option 2: Social Connections
**Let users login with Google, GitHub, etc.**
##### Google OAuth Setup
1. **Create Google Cloud project**:
- Visit: https://console.cloud.google.com
- Create new project: "My App Auth"
- Enable Google+ API
2. **Create OAuth credentials**:
- APIs & Services → Credentials → Create OAuth 2.0 Client ID
- Authorized redirect URIs:
- `https://YOUR_DOMAIN/login/callback`
- `https://YOUR_DOMAIN/login/callback?connection=google-oauth2`
- Copy: Client ID and Client Secret
3. **Add to Auth0**:
```
Auth0 Dashboard → Connections → Social → Google
Client ID: [Paste from Google Cloud]
Client Secret: [Paste from Google Cloud]
Enable for: [Your application]
```
##### GitHub OAuth Setup
1. **Create GitHub OAuth App**:
- Visit: https://github.com/settings/developers
- Register new OAuth application
- Authorization callback URL:
- `https://YOUR_DOMAIN/login/callback`
- Copy: Client ID and Client Secret
2. **Add to Auth0**:
```
Auth0 Dashboard → Connections → Social → GitHub
Client ID: [Paste from GitHub]
Client Secret: [Paste from GitHub]
Enable for: [Your application]
```
---
#### Option 3: Enterprise Connections (Active Directory/LDAP)
**For company employees using company email**
**Setup Active Directory**:
```
Auth0 Dashboard → Connections → Enterprise → Active Directory/LDAP
Name: Company AD
LDAP URL: ldap://ad.company.com:389
Bind DN: admin@company.com
Bind Password: [AD admin password]
Base DN: cn=users,dc=company,dc=com
Mapping:
- Email: mail
- Name: displayName
- Username: sAMAccountName
Enable for: [Your application]
```
**Result**: Users can login with company credentials, no password duplication
---
### Step 4: Create API
If your frontend needs to call protected APIs:
```
Auth0 Dashboard → APIs → Create API
Name: My API
Identifier: https://api.myapp.com
Signing Algorithm: RS256
Scopes:
+ read:items (Read access to items)
+ write:items (Write access to items)
+ delete:items (Delete items)
+ admin (Full admin access)
```
**Usage in App**:
```typescript
// Request these scopes during login
Auth0Provider({
authorizationParams: {
scope: 'openid profile email read:items write:items'
}
})
// Access token will include these scopes
// Backend validates scopes before allowing access
```
---
### Step 5: Basic Security Configuration
#### Enable Multi-Factor Authentication (MFA)
```
Auth0 Dashboard → Connections → Authenticators
Enable:
- Google Authenticator ✅
- SMS (optional)
- Email OTP
For application:
- Require MFA: Yes / No / Per-user rule
```
**Optional**: Require MFA for certain users:
```javascript
// Auth0 Rule: Enforce MFA for admin users
module.exports = function(user, context, callback) {
if (user.email.endsWith('@admin.company.com')) {
context.multifactor = {
provider: 'google-authenticator',
allowRememberBrowser: false
}
}
callback(null, user, context)
}
```
---
#### Set Token Expiration
```
Auth0 Dashboard → Applications → Settings → Advanced
Token Settings:
- ID Token Expiration: 36000 (10 hours)
- Access Token Expiration: 600 (10 minutes) ← IMPORTANT
- Refresh Token Expiration: 2592000 (30 days)
- Refresh Token Rotation: Enabled ✅
```
**Why short access token?**
- If leaked, attacker has limited time window
- Refresh tokens can be rotated automatically
- Best practice: 5-15 minutes
---
#### Enable HTTPS for Callback URLs
```
Auth0 Dashboard → Applications → Settings
Allowed Callback URLs:
- Production: https://myapp.com/callback ✅
- Staging: https://staging.myapp.com/callback ✅
- Local dev: http://localhost:3000/callback (only for dev)
Allowed Logout URLs:
- Production: https://myapp.com ✅
- Staging: https://staging.myapp.com ✅
- Local dev: http://localhost:3000 (only for dev)
```
---
### Step 6: Generate Environment Variables
Based on your setup, create `.env.local`:
```env
# Auth0 Configuration
AUTH0_DOMAIN=YOUR_DOMAIN.auth0.com
AUTH0_CLIENT_ID=YOUR_CLIENT_ID
AUTH0_CLIENT_SECRET=YOUR_CLIENT_SECRET
AUTH0_CALLBACK_URL=http://localhost:3000/callback
# For Next.js
AUTH0_BASE_URL=http://localhost:3000
AUTH0_SECRET=use [node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"]
# For APIs
AUTH0_AUDIENCE=https://api.myapp.com
AUTH0_SCOPE=openid profile email read:items
# API Configuration
API_URL=http://localhost:3001
```
---
## Quick Reference
### URLs to Save
- **Auth0 Dashboard**: https://manage.auth0.com
- **Your Tenant**: https://YOUR_DOMAIN.auth0.com
- **Login Page**: https://YOUR_DOMAIN.auth0.com/login
### Common Task Commands
**View users**:
```
Auth0 Dashboard → User Management → Users
```
**View logs**:
```
Auth0 Dashboard → Logs (Real-time logs of auth events)
```
**View rules**:
```
Auth0 Dashboard → Rules (Custom logic for auth flow)
```
**Reset user password**:
```
Auth0 Dashboard → Users → Select user → Actions → Reset password
```
---
## Verification Checklist
- [ ] Auth0 tenant created
- [ ] Application configured (SPA/Web/M2M/Native)
- [ ] Callback URLs set (http://localhost:3000/callback)
- [ ] Logout URLs set (http://localhost:3000)
- [ ] Connection enabled (Database/Google/GitHub/AD)
- [ ] API created with scopes
- [ ] MFA configured
- [ ] Token expiration set (10 min for access tokens)
- [ ] Environment variables generated
- [ ] Test login from Auth0 dashboard works
---
## Next Steps
After setup completes:
1. **Install SDK for your framework**:
- React: `/oauth-implement react`
- Next.js: `/oauth-implement nextjs`
- Node.js: `/oauth-implement nodejs`
2. **Run security audit**:
- `/oauth-security-audit`
3. **Test your implementation**:
- Try login flow
- Check token in browser dev tools
- Verify API access
4. **Deploy to production**:
- Update callback URLs to production domain
- Update environment variables
- Enable HTTPS everywhere
- Consider Auth0 compliance (GDPR, HIPAA, SOC2)
---
## Troubleshooting
**Q: Callback URL mismatch error?**
A: Ensure your callback URL in Auth0 exactly matches redirect_uri in your app (including http/https and port)
**Q: Connection not showing in login?**
A: Check that connection is enabled for your application (Connections → Select connection → Applications toggle)
**Q: Can't create users via signup?**
A: Ensure "Allow Signup" is enabled in Database connection settings
**Q: Users can't login with social connection?**
A: Verify social connection is enabled for your application
---
**Status**: Setup wizard complete!
**Next command**: `/oauth-implement [framework]` to add auth to your app

View File

@@ -0,0 +1,555 @@
---
description: Troubleshooting guide for common Auth0 OAuth issues
---
# OAuth Troubleshooting Guide
Solutions for common Auth0 OAuth problems.
## Quick Start
```bash
/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**:
```typescript
// 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**:
```bash
# 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)**:
```typescript
// 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)**:
```typescript
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**:
```bash
# 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):
```typescript
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**:
```typescript
// Make sure credentials are included
fetch('/api/items', {
headers: { Authorization: `Bearer ${token}` },
credentials: 'include' // Important for cookies
})
```
**Test**:
```bash
# 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**:
```typescript
// 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**:
```typescript
// 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**:
```typescript
// 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**:
```javascript
// 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**:
```bash
# 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):
```typescript
// 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):
```typescript
// 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**:
```bash
# 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**:
```bash
# 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
```javascript
// 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
```bash
# In browser DevTools → Network tab
# Select API request
# Check headers:
# Authorization: Bearer {token}
# Content-Type: application/json
```
### 4. Enable Debug Mode
```typescript
// 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!