DEV Community

Cover image for Integrating Clerk With Zuplo For Seamless API Authentication
Adrian Machado for Zuplo

Posted on • Originally published at zuplo.com

Integrating Clerk With Zuplo For Seamless API Authentication

Authentication is at the core of Zuplo. When developers need API management, one of the main features they need is authentication and security for their API endpoints.

That's why we offer API key management, allowing users to manage access to their APIs easily. However, API keys are just one way to manage access to protected resources. Zuplo has an array of JSON Web Token (JWT) policies that allow you to use JWTs from specialized authentication providers.

One such provider is Clerk. Clerk is a user management platform that allows developers to build out entire authentication solutions with only a few changes to their code. We see Clerk as an ideal partner to Zuplo, allowing developers to build the authentication flow they need to secure their APIs.

In this article, we will explain why we see Clerk and Zuplo playing so well together and then show you how easy it is to step up Clerk and Zuplo for API access control.

Why Clerk is Ideal For API Management

When talking about API access control, we're really talking about two things.

First, we're talking about restricting access. You could leave your API open for the world to consume (and some APIs do that), but that's probably not what you want. So, you need an API management tool such as Zuplo to control access to your API.

Second, we're talking about allowing access to your users. Zuplo does have API key management for this, but even when using this option, developers still need to build the entire authentication infrastructure to have 'users.' This is where Clerk comes in. Clerk gives you a secure user management and authentication experience. Here are the platform's core features:

  1. Enhanced user management: Clerk offers pre-built UI components and APIs
    for user management, including sign-up, sign-in, and account management. Developers can drop these into their code and immediately protect their entire application. Behind the scenes, Clerk offers an easy way to manage users.

  2. Authentication options: Clerk supports various authentication
    strategies, such as passwords, email codes or links, and OAuth. This allows you to choose the best method for your application's requirements and enhance its security.

  3. Organization management: Clerk supports shared accounts for project and
    team leaders, with members having elevated privileges to manage access to the organization's data and resources.

  4. Security features: Clerk includes various security features, such as
    account lockout, brute-force protection, bot protection, user bans, and more.

  5. Customization: Clerk's components can be customized to match the look
    and feel of your application. This allows you to create a consistent and branded user experience.

When coupled with Zuplo, the above makes API access control much easier. With Clerk integrated, we have user management capabilities, which we can use to create our API keys. We also have much more secure authentication using MFA and OAuth. We can also expand to defining API access across organizations and take advantage of Clerk's security measures to build more robust access control and protect against potential threats. As importantly, though, we can take advantage of Clerk's JWTs. JWTs are used by most popular authentication and user management providers because they are highly flexible and secure. They enable stateless authentication, meaning the server doesn't need to maintain session state. This is particularly useful in distributed systems like microservices.

JWTs can also include claims, which are assertions about the user, such as user role or permissions. This capability allows for fine-grained access control, enabling APIs to make more informed, dynamic decisions about who can access what resources. JWTs also support expiration, reducing risks associated with long-lived credentials. Being stateless, JWTs reduce the need for frequent database lookups to authenticate each request, leading to better performance. Integrating Clerk's JWTs enhances overall API security and usability in API management. If this has convinced you, let's combine Clerk and Zuplo for access control.

How to Use Clerk With Zuplo

Setting up Zuplo to work with Clerk is going to be extremely easy. To start, you'll need a Clerk and a Zuplo account.

You'll also need an application that is using the Clerk SDK. We won't walk you through all of that here as Clerk already has great documentation on setting up Clerk. Here, we'll use a Next.js app using the basic Next.js Clerk setup.

To integrate Clerk with Zuplo, we will only build one additional page. We'll set up an 'account' page that will serve as a mock page that might require an API response--this page might have to call a backend API or database to populate information about the user. Within that page, add this code:

//  app/account/page.jsx

import { auth } from "@clerk/nextjs";

async function getData() {
  const { getToken } = auth();

  const token = await getToken();
  console.log(token);
}

export default async function Page() {
  const response = await getData();
  //  add  the  data  to  the  page
  console.log(response);
  return <div></div>;
}
Enter fullscreen mode Exit fullscreen mode

Here, we're importing the auth() helper from Clerk that returns our authentication object. When we run this helper within our getData function, we deconstruct the getToken() function from this authentication object.

We then await the resolution of the getToken promise, retrieving the user's authentication token. The getData function is run when the page is rendered on the server (all this happens within a React Server Component. Nothing is being fetched directly from the client). Currently, the page itself doesn't render any text on the client.

In Clerk, the user's authentication token is a JWT token that we can then send to a server as part of an authentication process. That is exactly what we are going to do here. We will send that token to Zuplo to authenticate access to whatever Zuplo is protecting. So, let's move over to the Zuplo side of the house. You can find up-to-date documentation on integrating Clerk with Zuplo in the Clerk JWT Auth Policy documentation. But briefly, what we need to do is:

  • Retrieve your FRONTEND API URL from your Clerk dashboard.

  • Set this as an environmental variable called CLERK_FRONTEND_API_URL within
    Zuplo.

  • In the Zuplo Portal's Route Designer, create a new GET route and add the Clerk
    JWT Auth policy to your desired route.

Your policy will look something like this:

{
  "name": "my-clerk-jwt-auth-inbound-policy",
  "policyType": "clerk-jwt-auth-inbound",
  "handler": {
    "export": "ClerkJwtInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "allowUnauthenticatedRequests": false,
      "frontendApiUrl": "$env(CLERK_FRONTEND_API_URL)"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

For our route, we will set the Request Handler as the Hello World function so we can easily see the client's results. But this is where you'll set your protected API route.

Save this and copy your Zuplo Gateway URL, and we will be ready to head back to our code. We'll expand our code from above to use the JWT token as an authorization header for our Zuplo gateway:

import { NextResponse } from "next/server";
import { auth } from "@clerk/nextjs";

async function getData() {
  const { getToken } = auth();

  const token = await getToken();
  const res = await fetch(
    "https://coral-hare-main-aa0b123.d2.zuplo.dev/path-0",
    {
      headers: {
        Authorization: `Bearer ${token} `,
      },
    },
  );

  const data = await res.json();
  return data;
}

export default async function Page() {
  const response = await getData();
  //  add  the  data  to  the  page
  return (
    <div>
      <p>{response}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Here, we use a fetch to our gateway with the authorization header. This header is our JWT token prepended with Bearer. We can now use the output of our getData function on our page, rendering the text received:

Result of using Clerk and Zuplo

That is really all there is to it. What have we done?

  • Set up Clerk to handle authentication and session management within our application
  • Extracted the JWT token Clerk uses for authentication
  • Set up a policy within Zuplo that uses this JWT token for access control
  • Passed the token from Clerk to Zuplo
  • Accessed our backend function and passed the response to the client for the end user

All that with a single policy, Clerk API call, and fetch to Zuplo.

Simple API Security With Clerk and Zuplo

The best solutions are often the simplest. Adding Clerk as the user management for your Zuplo API management is extremely simple. But hidden beneath that simplicity is a lot of power. You can expand your policies on the Zuplo side or code and JWTs on the Clerk side to create more granular and robust access control for your APIs or functions.

Whether you keep it simple or build stronger authentication and authorization with Clerk and Zuplo, you're leveraging a combination of Clerk's robust user management and authentication features with Zuplo's powerful API management capabilities. This partnership ensures that your API is secure, highly functional, and user-friendly, offering a seamless experience for both developers and end-users.

Top comments (0)