A Comprehensive Guide to Using `koa-jwt` for Secure Koa.js API Authentication

Introduction to `koa-jwt`

The `koa-jwt` library is a popular middleware for Koa.js applications, providing robust JWT (JSON Web Token) authentication. This library helps in securing your API endpoints by verifying incoming requests’ JWT tokens. In this guide, we’ll explore `koa-jwt`’s APIs with detailed explanations and practical code examples.

Installation

npm install koa-jwt jsonwebtoken

API Examples

Basic Setup

First, let’s set up `koa-jwt` with a secret key to protect your routes.

const Koa = require('koa');
const jwt = require('koa-jwt');

const app = new Koa();

// Secret key
const secret = 'your_secret_key';

// Middleware for JWT authentication
app.use(jwt({ secret }));

app.listen(3000);
console.log('Server is running on port 3000');

Creating JWT Tokens

Create tokens using the `jsonwebtoken` library, which can then be used for authentication.

const jwt = require('jsonwebtoken');

const token = jwt.sign({ username: 'user1' }, 'your_secret_key', { expiresIn: '1h' });
console.log('JWT Token:', token);

Using Custom Token Extraction

Define a custom function to extract the token from requests.

app.use(jwt({
  secret,
  getToken: (ctx) => {
    if (ctx.headers.authorization && ctx.headers.authorization.split(' ')[0] === 'Bearer') {
      return ctx.headers.authorization.split(' ')[1];
    } else if (ctx.query && ctx.query.token) {
      return ctx.query.token;
    }
    return null;
  }
}));

Handling Authentication Errors

Handle errors from JWT validation more gracefully with a custom error handler.

app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    if (err.status === 401) {
      ctx.status = 401;
      ctx.body = 'Protected resource, use Authorization header to get access';
    } else {
      throw err;
    }
  }
});

app.use(jwt({ secret }));

Skipping Authentication for Public Routes

Use the `.unless()` method to exclude certain routes from authentication requirements.

const publicRoutes = ['/login', '/register'];

app.use(jwt({ secret }).unless({ path: publicRoutes }));

app.use(async ctx => {
  if (ctx.url === '/login') {
    // handle login
  } else if (ctx.url === '/register') {
    // handle registration
  } else {
    ctx.body = 'Protected resource';
  }
});

Example Koa.js App with `koa-jwt`

const Koa = require('koa');
const jwt = require('jsonwebtoken');
const koaJwt = require('koa-jwt');

const app = new Koa();
const secret = 'your_secret_key';

const publicRoutes = ['/login'];

// Middleware
app.use(koaJwt({ secret }).unless({ path: publicRoutes }));

app.use(async (ctx, next) => {
  if (ctx.url === '/login' && ctx.method === 'POST') {
    const { username, password } = ctx.request.body;
    // Validate user credentials (this is just an example)
    if (username === 'test' && password === 'password') {
      const token = jwt.sign({ username }, secret, { expiresIn: '1h' });
      ctx.body = { token };
    } else {
      ctx.status = 401;
      ctx.body = 'Invalid credentials';
    }
  } else {
    await next();
  }
});

app.use(async ctx => {
  ctx.body = 'Protected resource';
});

app.listen(3000);
console.log('Server running on port 3000');

Hash: 77a64ab2dea833701190f94ae75e32ced316521b17c48e127b03ecdff16a3b98

Leave a Reply

Your email address will not be published. Required fields are marked *