Loading...
Loading...
Use when adding Auth0 token validation to Express or Node.js APIs - integrates express-oauth2-jwt-bearer SDK to protect Node.js API endpoints with JWT Bearer authentication, scope-based RBAC, claim validation, and optional DPoP support
npx skill4agent add auth0/agent-skills express-oauth2-jwt-bearerexpress-oauth2-jwt-bearerAgent instruction: Before providing SDK setup instructions, fetch the latest release version by running:bashgh api repos/auth0/node-oauth2-jwt-bearer/releases/latest --jq '.tag_name'Use the returned version in alldependency lines instead of any hardcoded version below.package.json
npm install -g @auth0/auth0-cli| Use Case | Recommended Skill |
|---|---|
| Building a server-side web app with login UI (Express sessions) | |
| Building a Next.js app with server-side auth | |
| Building a React/Angular/Vue SPA | |
| Building a React Native or mobile app | |
| ASP.NET Core Web API | |
| Go API with JWT middleware | |
| Python API (Flask/FastAPI) | |
Node.js API using the older | |
Agent instruction: Follow these steps to integrateinto the user's Node.js API project.express-oauth2-jwt-bearer
Fetch latest version (see instruction above). Install the SDK:bashnpm install express-oauth2-jwt-bearer Configure Auth0 — follow. If the user already provided their Auth0 Domain and API Audience in the prompt, use them directly — skip the bootstrap script and do NOT callreferences/setup.mdto re-confirm. Otherwise, offer automatic setup via bootstrap script or manual setup.AskUserQuestion Set up middleware — add toorapp.js:server.jsjavascriptimport { auth } from 'express-oauth2-jwt-bearer'; const checkJwt = auth({ issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`, audience: process.env.AUTH0_AUDIENCE, }); app.use(checkJwt); // apply globally, or per-route Protect endpoints — apply middleware globally or to specific routes:javascript// Global protection app.use(checkJwt); // Or per-route app.get('/api/private', checkJwt, (req, res) => { res.json({ sub: req.auth.payload.sub }); }); Add RBAC (optional) — useorrequiredScopes()for permission-based access:claimIncludes()javascriptimport { auth, requiredScopes, claimIncludes } from 'express-oauth2-jwt-bearer'; app.get('/api/messages', checkJwt, requiredScopes('read:messages'), (req, res) => { res.json({ messages: [] }); });Important:accepts a single argument — a space-separated string or an array. Do NOT pass multiple string arguments:requiredScopessilently ignores everything after the first. UserequiredScopes('read:msg', 'write:msg')orrequiredScopes('read:msg write:msg')instead.requiredScopes(['read:msg', 'write:msg']) Verify the integration — build and test:bashnode server.js curl http://localhost:3000/api/private # should return 401 curl -H "Authorization: Bearer <token>" http://localhost:3000/api/private # should return 200 Failcheck: If the server fails to start or tokens are rejected unexpectedly, checkfor common issues. After 5-6 failed iterations, usereferences/api.mdto ask the user for more details about their environment.AskUserQuestion
| Mistake | Symptom | Fix |
|---|---|---|
| Created an Application instead of an API in Auth0 Dashboard | Token validation fails; wrong audience | Create a new API (Resource Server) in Auth0 Dashboard → APIs |
| Audience doesn't match API identifier exactly | | Copy the exact API Identifier string from Auth0 Dashboard → APIs |
Domain includes | | Use hostname only: |
Checking | 403 always returned or permissions ignored | Use |
| CORS not configured before auth middleware | Preflight OPTIONS requests return 401 | Add |
| | Add |
| | Verify |
| Function | Description | Returns |
|---|---|---|
| JWT Bearer validation middleware | |
| Validates token has all required scopes | |
| Validates token has at least one scope | |
| Validates a claim equals a value | |
| Validates claim includes all values | |
| Custom claim validation function | |
| Option | Type | Description |
|---|---|---|
| | Auth0 domain with |
| | API Identifier from Auth0 Dashboard (required unless using env vars) |
| | Signing algorithm (default: |
| | Set |
| | Clock skew tolerance in seconds (no default; undefined unless set) |
| | DPoP configuration (see integration.md) |
| Variable | Description |
|---|---|
| Auth0 domain with |
| API Identifier (auto-detected by SDK) |
req.authreq.auth.payload // Decoded JWT payload (sub, iss, aud, exp, permissions, etc.)
req.auth.header // JWT header (alg, typ, kid)
req.auth.token // Raw JWT stringnode-oauth2-jwt-bearer| Package | Purpose |
|---|---|
| Main package. Express middleware for JWT Bearer validation. Published to npm. |
| Low-level JWT verification utilities (used internally). |
| RFC 6750 Bearer token extraction (used internally). |
express-oauth2-jwt-bearer| Auth Pattern | SDK | When to Use |
|---|---|---|
| JWT Bearer (stateless) | | APIs called by SPAs, mobile apps, M2M clients |
| Session-based (stateful) | | Web apps with login UI and server-side sessions |
# Get test token from Auth0 Dashboard → APIs → your API → Test tab
# Copy the token, then:
# 1. Verify 401 on protected route (no token)
curl -v http://localhost:3000/api/private
# 2. Verify 200 with valid token
curl -H "Authorization: Bearer <paste-token-here>" http://localhost:3000/api/private
# 3. Verify 403 with valid token but missing scope
curl -H "Authorization: Bearer <paste-token-here>" http://localhost:3000/api/admin
# 4. Verify CORS preflight
curl -v -X OPTIONS http://localhost:3000/api/private \
-H "Origin: http://localhost:5173" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: Authorization"