Backend API authentication patterns with Clerk JWT middleware and route protection. Use when building REST APIs, GraphQL APIs, protecting backend routes, implementing JWT validation, setting up Express middleware, or when user mentions API authentication, backend security, JWT tokens, or protected endpoints.
Limited to specific tools
Additional assets for this skill
This skill is limited to using the following tools:
examples/graphql-api.mdexamples/rest-api.mdexamples/webhooks.mdscripts/generate-api-client.shscripts/setup-api-auth.shscripts/test-api-auth.shtemplates/api-middleware.tstemplates/api-routes.tstemplates/backend-sdk-setup.tstemplates/fastapi-middleware.pyBackend API authentication skill for Clerk integration. Provides JWT middleware, route protection patterns, and API client generation for REST and GraphQL backends.
Run the setup script to configure backend authentication:
bash scripts/setup-api-auth.sh <framework> <project-path>
Supported Frameworks:
express - Express.js middlewarefastify - Fastify decoratorsnextjs - Next.js API route helpersfastapi - FastAPI dependencies (Python)What it does:
For Express/Node.js backends:
Use the api-middleware.ts template:
import { requireAuth } from './middleware/clerk-auth'
// Protect individual routes
app.get('/api/protected', requireAuth, (req, res) => {
const userId = req.auth.userId
res.json({ message: 'Protected data', userId })
})
// Protect route groups
app.use('/api/admin', requireAuth, adminRouter)
For Next.js API routes:
Use the api-routes.ts template:
import { withAuth } from '@/lib/clerk-middleware'
export default withAuth(async (req, res) => {
const { userId } = req.auth
// Protected route logic
})
For GraphQL:
Use the graphql-clerk.ts example:
import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node'
const server = new ApolloServer({
context: ({ req }) => ({
userId: req.auth?.userId,
user: req.auth?.user
})
})
app.use('/graphql', ClerkExpressRequireAuth(), apolloMiddleware)
Create type-safe API clients with authentication headers:
bash scripts/generate-api-client.sh <api-type> <output-path>
API Types:
rest - REST API client with fetchgraphql - GraphQL client with Apolloaxios - Axios-based REST clienttrpc - tRPC client with auth contextGenerated Client Features:
Run comprehensive authentication tests:
bash scripts/test-api-auth.sh <project-path>
Test Coverage:
// middleware/clerk-auth.ts
import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node'
export const requireAuth = ClerkExpressRequireAuth({
onError: (error) => {
console.error('Auth error:', error)
return { status: 401, message: 'Unauthorized' }
}
})
// Optional auth (allows both authenticated and anonymous)
export const optionalAuth = ClerkExpressWithAuth()
// lib/jwt-verify.ts
import { verifyToken } from '@clerk/backend'
export async function validateJWT(token: string) {
try {
const payload = await verifyToken(token, {
secretKey: process.env.CLERK_SECRET_KEY
})
return { valid: true, userId: payload.sub }
} catch (error) {
return { valid: false, error: error.message }
}
}
// middleware/rbac.ts
export function requireRole(role: string) {
return async (req, res, next) => {
const { userId } = req.auth
const user = await clerkClient.users.getUser(userId)
if (user.publicMetadata.role !== role) {
return res.status(403).json({ error: 'Forbidden' })
}
next()
}
}
// Usage
app.get('/api/admin', requireAuth, requireRole('admin'), handler)
// graphql/context.ts
import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node'
export const context = async ({ req }) => {
const userId = req.auth?.userId
if (!userId) {
throw new AuthenticationError('Must be authenticated')
}
const user = await clerkClient.users.getUser(userId)
return {
userId,
user,
isAdmin: user.publicMetadata.role === 'admin'
}
}
Required environment variables (always use placeholders in committed files):
# .env.example
CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key_here
CLERK_SECRET_KEY=your_clerk_secret_key_here
# Optional: For webhook verification
CLERK_WEBHOOK_SECRET=your_webhook_secret_here
# Optional: For custom JWT configuration
CLERK_JWT_KEY=your_jwt_key_here
Issue: "Invalid token" errors
CLERK_SECRET_KEY is correctIssue: CORS errors on API requests
Issue: "Missing userId" in request context
Issue: GraphQL authentication not working
templates/api-middleware.ts - Express/Node.js middlewaretemplates/api-routes.ts - Next.js API route helperstemplates/backend-sdk-setup.ts - Backend SDK initializationtemplates/fastapi-middleware.py - FastAPI authentication dependenciesexamples/rest-api.md - Complete REST API with authenticationexamples/graphql-api.md - GraphQL server with Clerk contextexamples/webhooks.md - Webhook event handling and processingscripts/setup-api-auth.sh - Configure backend authenticationscripts/generate-api-client.sh - Create authenticated API clientsscripts/test-api-auth.sh - Test authentication flowsThis skill follows strict security rules:
.gitignore protection documentedReference: @docs/security/SECURITY-RULES.md