Express SDK

@get401/express provides authentication middleware for Express. Includes soft population middleware, hard-blocking route guards, and per-route role/scope protection — fully typed with TypeScript.

GitHub: get401/js-express

Installation

npm install @get401/express cookie-parser

cookie-parser is required so that req.cookies is populated before the middleware reads the aact cookie.

Setup

import express from 'express'
import cookieParser from 'cookie-parser'
import { Get401Auth } from '@get401/express'
 
const auth = new Get401Auth({
  appId: process.env.GET401_APP_ID!,
  origin: process.env.GET401_ORIGIN!,
})
 
const app = express()
app.use(cookieParser())

Usage

Pattern A - global soft middleware + per-route guards

Best for apps where most routes are protected:

app.use(auth.authenticate()) // never blocks, just populates req.get401Claims
 
app.get('/public', (req, res) => {
  res.json({ message: 'No auth needed' })
})
 
app.get('/me', auth.requireAuth(), (req, res) => {
  res.json({ userId: req.get401Claims!.sub })
})
 
app.delete('/admin/user/:id', auth.requireRoles(['ADMIN']), (req, res) => {
  res.json({ deleted: req.params.id })
})

Pattern B - standalone per-route

Best for APIs where each route is configured independently:

app.get('/me', auth.requireAuth(), (req, res) => {
  res.json({ userId: req.get401Claims!.sub, roles: req.get401Claims!.roles })
})

Middleware Reference

Method Description
auth.authenticate() Soft - populates req.get401Claims, never blocks
auth.requireAuth() Returns 401 if cookie is missing, expired, or invalid
auth.requireRoles(roles, options?) Returns 401 if not authenticated, 403 if roles don't match
auth.requireScope(scope) Returns 401 if not authenticated, 403 if scope is missing
// Require at least one role
app.get('/dashboard', auth.requireRoles(['USER']), handler)
 
// Require all roles
app.post('/superadmin', auth.requireRoles(['ADMIN', 'SUPERUSER'], { requireAll: true }), handler)
 
// Require scope
app.post('/reports/export', auth.requireScope('reports:export'), handler)

Claim Helpers

import { hasRole, hasScope, getScopes } from '@get401/express'
 
app.get('/premium', auth.requireAuth(), (req, res) => {
  if (!hasRole(req.get401Claims!, 'PREMIUM')) {
    return res.status(403).json({ error: 'Premium subscription required.' })
  }
  res.json({ content: '...' })
})

HTTP Responses

Situation Status
Missing aact cookie 401
Expired token 401
Invalid / tampered token 401
Missing role 403
Missing scope 403
get401 backend unreachable 503