Koa JWT Authentication Middleware

1.0.3 · abandoned · verified Wed Apr 22

koa-jwt2 is Koa middleware designed for authenticating HTTP requests using JSON Web Tokens (JWT). It validates incoming JWTs and populates `ctx.state.user` (or a configurable property) with the decoded payload, making it available for subsequent middleware to handle authorization and access control. Key features include support for `audience`, `issuer`, and `expiration` validation, handling of base64 URL-encoded secrets, and verification with public/private key pairs. It integrates `koa-unless` for specifying unprotected paths and offers advanced options like custom token extraction via `getToken` and multi-tenancy support through an asynchronous secret function. The current stable version is 1.0.3. However, the package's GitHub repository has been archived, indicating it is no longer actively maintained, and thus its release cadence is effectively ceased. This makes it distinct from more actively developed alternatives, though its multi-tenancy secret resolution feature remains notable.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart sets up a basic Koa application with two routes: `/token` to issue a JWT and `/protected` which is secured by `koa-jwt2`. It demonstrates how to configure the middleware with a secret, access the decoded user payload from `ctx.state.user`, and use the `unless` option to exclude the token issuance route from JWT validation. It requires `@koa/router` and `jsonwebtoken`.

const Koa = require('koa');
const Router = require('@koa/router');
const jwt = require('koa-jwt2');

const app = new Koa();
const router = new Router();

const SECRET = process.env.JWT_SECRET || 'a-very-strong-secret-for-jwt-signing';

// Middleware to generate a simple JWT for testing
router.get('/token', async (ctx) => {
  const jsonwebtoken = require('jsonwebtoken');
  const token = jsonwebtoken.sign({ id: 1, name: 'testuser', admin: false }, SECRET, { expiresIn: '1h' });
  ctx.body = { token };
});

// Protected route
router.get('/protected', jwt({ secret: SECRET }).unless({ path: ['/token'] }), async (ctx) => {
  if (!ctx.state.user) {
    ctx.status = 401;
    ctx.body = { message: 'Authentication required' };
    return;
  }
  ctx.body = { message: `Hello, ${ctx.state.user.name}! You accessed a protected route.`, user: ctx.state.user };
});

app.use(router.routes()).use(router.allowedMethods());

const port = 3000;
app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
  console.log('GET /token to get a JWT.');
  console.log('GET /protected with Authorization: Bearer <token> header.');
});

view raw JSON →