Skip to main content

api-auth-express

@rtorcato/api-auth-express provides two Express middleware functions that verify a JWT and attach the decoded payload to req.user. Failures pass an UnauthorizedError to Express's error handler — pair with api-errors-express for automatic JSON 401 responses.

Install

pnpm add @rtorcato/api-auth @rtorcato/api-auth-express express

express is a peer dependency (^4.18 || ^5) — you bring your own version.

authMiddleware

Requires a valid token. Returns 401 if the token is missing or invalid.

import express from 'express'
import { authMiddleware } from '@rtorcato/api-auth-express'
import { errorHandler } from '@rtorcato/api-errors-express'

const app = express()
const auth = authMiddleware(process.env.JWT_SECRET)

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

app.use(errorHandler())

The token is read from Authorization: Bearer <token> first, then from a cookie named token. Customise the cookie name:

const auth = authMiddleware(process.env.JWT_SECRET, { cookieName: 'access_token' })

Pass verifyOptions to control JWT verification (algorithm, audience, issuer, etc.):

const auth = authMiddleware(secret, {
verifyOptions: { algorithms: ['HS256'], audience: 'my-api' },
})

optionalAuthMiddleware

Tries to verify the token but never blocks the request. If a valid token is present req.user is set; if not (missing, expired, malformed), the request continues with req.user undefined.

import { optionalAuthMiddleware } from '@rtorcato/api-auth-express'

const optAuth = optionalAuthMiddleware(process.env.JWT_SECRET)

app.get('/feed', optAuth, (req, res) => {
const feed = req.user ? personalFeed(req.user.sub) : publicFeed()
res.json(feed)
})

req.user typing

The middleware augments Express's Request interface globally:

// automatically in scope after importing api-auth-express
req.user // jwt.JwtPayload | undefined

To extend the type for your own claims:

declare global {
namespace Express {
interface Request {
user?: { sub: string; role: 'admin' | 'user' }
}
}
}