Jordi Olle Logo
Back

Building with Purpose 2: Adding authentication with Clerk

Published on March 21, 2025

Building with Purpose 2: Adding authentication with Clerk

This part is going to be pretty close to the guide provided by Clerk, but we’ll add a few things to make it look different.

I’m assuming you know how to create an account at Clerk, so we’ll skip that part.

Once registered, it’ll ask you to create a new project. When that is done, we’ll go to the Configure tab and select API Keys.

In the right section, we’ll see the Pushable Key and the Secret Key. We need to copy and paste them into our .env file like this:

CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY 
CLERK_SECRET_KEY=YOUR_SECRET_KEY

Now we can install Clerk in our Fastify app with:

pnpm add @clerk/fastify

Once this is done, we need to configure the clerkPlugin() for all the routes of our application. We’ll import it and add this code right after the server declaration:

import { clerkPlugin } from "@clerk/fastify"

...

server.register(clerkPlugin, {
    publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
    secretKey: process.env.CLERK_SECRET_KEY,
});

It’s time to create a route to test if Clerk is working (not 100%, as that will be when we are building the frontend part because according to te’ll need our frontend running so we can get a long-lived JWT).

For this, we’ll follow the guide provided by them. We’ll create a “/protected” route right after the “/” route. There, we’ll use getAuth and clerkClient to check if the user exists or not and return the correct answer.

It’ll be something like this:

import { clerkClient, clerkPlugin, getAuth } from '@clerk/fastify'

...

server.get("/protected", async (req, reply) => {
    try {
        const { userId } = getAuth(req);

        if (!userId) {
            return reply.code(401).send({ error: "User not found" });
        }

        const user = userId ? await clerkClient.users.getUser(userId) : null;

        return reply.send({ message: "User authenticated successfully", user });
    } catch (err) {
        server.log.error(err);
        return reply.code(500).send({ error: "Failed to authenticate user" });
    }
});

Right now, we have no way to specify the user as we want. We just want to make sure it works by at least getting a "User not found" message.

Looks like it’s working properly. We can now move on to the next step, which is configuring Prisma and the database, which will be PostgreSQL.

That's it for this part.

Salut, Jordi.

Check the repository HERE.

Did you like this article? Read the original post on Hashnode.

Building with Purpose 2: Adding authentication with Clerk | Jordi Ollé