Express

Full integration guide for Clowk with Express

Install

pnpm add @clowk/express @clowk/core

Configure

app.ts
import express from 'express'
import { clowkMiddleware, requireAuth } from '@clowk/express'

const app = express()

Protect all routes

Apply clowkMiddleware globally to decode the JWT on every request. The decoded payload is available on req.auth:

app.use(clowkMiddleware({
  secretKey: process.env.CLOWK_SECRET_KEY,
}))

app.get('/dashboard', (req, res) => {
  res.json({ user: req.auth })
})

Middleware options

OptionTypeDescription
secretKeystringSecret key for JWT verification
tokenParamstringQuery param name (default: "token")
cookieKeystringCookie name (default: "clowk_token")

Protect specific routes

Use requireAuth() to gate individual routes. It returns 401 if no valid token is found:

app.get('/public', (req, res) => {
  res.json({ message: 'This is public' })
})

app.get('/dashboard', requireAuth(), (req, res) => {
  res.json({ user: req.auth })
})

req.auth type

When a valid token is present, req.auth contains the decoded JWT payload:

interface JwtPayload {
  iss?: string       // "clowk"
  sub?: string       // User UUID
  email?: string     // "jane@example.com"
  name?: string      // "Jane Doe"
  avatar_url?: string
  provider?: string  // "google" | "github" | "twitter" | "email"
  instance_id?: string
  app_id?: string
  iat?: number
  exp?: number
}

With clowkMiddleware, req.auth is null if no token is found (soft auth). With requireAuth, the request is rejected with 401 before reaching your handler.

Token extraction

The middleware extracts the JWT from (in order):

  1. Query parameter?token=eyJ...
  2. Authorization headerBearer eyJ...
  3. Cookieclowk_token

Full example

app.ts
import express from 'express'
import { clowkMiddleware, requireAuth } from '@clowk/express'

const app = express()

app.use(clowkMiddleware({
  secretKey: process.env.CLOWK_SECRET_KEY,
}))

app.get('/', (req, res) => {
  res.json({ authenticated: !!req.auth })
})

app.get('/profile', requireAuth(), (req, res) => {
  res.json({
    id: req.auth?.sub,
    email: req.auth?.email,
    name: req.auth?.name,
  })
})

app.listen(3000)

On this page