--- 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( ) ``` #### 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 } export function LogoutButton() { const { logout, isAuthenticated } = useAuth0() if (!isAuthenticated) return null return } export function Profile() { const { user, isAuthenticated } = useAuth0() if (!isAuthenticated) return

Not logged in

return (
{user?.name}

{user?.name}

{user?.email}

) } ``` #### 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
Loading...
if (!isAuthenticated) return
Please log in
return children } // In App.tsx } /> ``` #### 5. Call Protected API ```typescript // src/hooks/useApi.ts import { useAuth0 } from '@auth0/auth0-react' import { useEffect, useState } from 'react' export function useApi(url: string) { const { getAccessTokenSilently } = useAuth0() const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(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 (

Welcome, {session.user.name}

{session.user.name}
) } ``` #### 4. Login/Logout Links ```typescript // app/components/Nav.tsx import { getSession } from '@auth0/nextjs-auth0' export async function Nav() { const session = await getSession() return ( ) } ``` #### 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 " \ 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!