DEV Community

Zayne Komchi
Zayne Komchi

Posted on

Add JWT Authentication in Deno & Oak server using Kinde Authentication

A Comprehensive Guide to Adding Kinde Authentication to an Oak Server in Deno

This guide explains how to integrate Kinde authentication into an Oak server using Deno. While Kinde doesn't have a dedicated Deno SDK, Deno's ability to use npm packages allows us to leverage the Kinde JWT Validator for this purpose.

Prerequisites

To follow this guide, ensure you have the following:

  • Deno: A modern runtime for JavaScript and TypeScript.
  • Oak: A middleware framework for Deno's HTTP server.
  • Kinde JWT Validator: A library to validate Kinde's JSON Web Tokens (JWTs).
  • Your Kinde domain: For example, your_domain.kinde.com.

Steps to Add Authentication

Step 1: Add Oak to Your Deno Project

Use the following command to add Oak to your project:

deno add jsr:@oak/oak
Enter fullscreen mode Exit fullscreen mode

Step 2: Add Kinde JWT Validator

Install the Kinde JWT Validator npm package:

deno add npm:@kinde/jwt-validator
Enter fullscreen mode Exit fullscreen mode

Step 3: Implement Authentication Middleware

Create an index.ts file in the root of your project and add the following code:

import { Application } from "@oak/oak/application";
import { Router } from "@oak/oak/router";
import { validateToken } from "@kinde/jwt-validator"; // Import the validator

// Custom error class for handling authentication errors
class AuthorizationError extends Error {
  constructor(message: string) {
    super(message);
    this.name = "AuthorizationError";
  }
}

const app = new Application();
const rootRouter = new Router();

// Define a basic route
rootRouter.get("/", (ctx) => {
  ctx.response.body = "Delve V1.0.0";
});

// Middleware to authenticate Kinde JWTs
app.use(async (ctx, next) => {
  try {
    // Check for the Authorization header
    if (ctx.request.headers.has("Authorization")) {
      const token = ctx.request.headers.get("Authorization")?.replace("Bearer ", "");

      // Validate the token using the Kinde JWT Validator
      const validateResult = await validateToken({
        token: token,
        domain: "your_domain.kinde.com", // Replace with your Kinde domain
      });

      if (validateResult.valid) {
        // Token is valid; proceed to the requested route
        await next();
        return;
      } else {
        throw new AuthorizationError("Unauthorized, token not valid!");
      }
    } else {
      throw new AuthorizationError("Authorization token required!");
    }
  } catch (error) {
    // Handle authentication errors
    if (error instanceof AuthorizationError) {
      ctx.response.status = 401; // Unauthorized
      ctx.response.body = { error: error.message };
    } else {
      ctx.response.status = 500; // Internal Server Error
      console.error("Unhandled error occurred:", error);
    }
  }
});

// Register routes and methods
app.use(rootRouter.routes());
app.use(rootRouter.allowedMethods());

// Start the server on port 3000
app.listen({ port: 3000 });
console.log("Server is running on http://localhost:3000");
Enter fullscreen mode Exit fullscreen mode

Explanation of the Code

Custom AuthorizationError Class

This class standardizes error messages for authentication-related errors.

class AuthorizationError extends Error {
  constructor(message: string) {
    super(message);
    this.name = "AuthorizationError";
  }
}
Enter fullscreen mode Exit fullscreen mode

Middleware for Authentication

The middleware validates the JWT token from the Authorization header:

  1. Header Validation: Checks if the Authorization header exists.
  2. Token Validation: Uses the validateToken function from the Kinde JWT Validator to confirm the token's validity.
  3. Error Handling: Throws a 401 Unauthorized error for invalid or missing tokens and logs unexpected errors with a 500 status.

Running the Server

Once the code is set up, start your server with the following command:

deno run --allow-net index.ts
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:3000 in your browser or use a tool like curl to test the endpoint.


Conclusion

By following these steps, you’ve successfully added Kinde authentication to your Oak server in Deno. This approach ensures secure validation of client requests using JWTs, leveraging the flexibility of npm packages in the Deno ecosystem.

Top comments (0)