Clerk Webhooks for User Authentication
Exploring the benefits and implementation of Clerk webhooks for secure user authentication
I started working on an app called Sentivibe this weekend, which uses AI to analyze YouTube comment sentiment and provide actionable insights to help YouTubers grow their channels. In this post, I’ll walk you through how I developed a webhook using Clerk to add a User record to my database whenever someone authenticates with Clerk. I’ll describe the high-level workings of the code so that you can implement something similar in your projects.
What is Clerk?
Clerk is a user authentication and management platform designed to simplify and streamline the process of adding secure, reliable user authentication to web applications. By providing a set of APIs, SDKs, and UI components, Clerk takes care of the heavy lifting when implementing user authentication, allowing developers to focus on building their core application features.
Here are some benefits of using Clerk in your app:
Speed up development: With Clerk’s pre-built authentication components, you can quickly add sign-up, sign-in, password reset, and other user authentication features to your app, saving you valuable development time.
Enhance security: Clerk is built with safety in mind, ensuring that your user data is protected and industry-standard security practices are followed.
Improve user experience: Clerk provides a seamless and customizable authentication experience for your users, allowing you to tailor the look and feel of the authentication UI to match your app’s design.
Easily manage users: Clerk offers a user management dashboard that makes it easy to manage user accounts, monitor authentication events, and troubleshoot issues.
What are Webhooks?
As your application grows and evolves, keeping track of various events happening within the system is essential. One such event is user authentication. When a user authenticates with Clerk, it’s helpful to store relevant user information in your database, so you can efficiently manage user-related data and provide personalized experiences.
That’s where webhooks come into play. Webhooks are essentially user-defined HTTP callbacks triggered by specific events. They provide a powerful mechanism to listen for and react to events in real time. Clerk supports webhooks, allowing you to be notified of various events, such as user creation, user updates, and more.
In the context of Sentivibe, we want to create a webhook to listen to the user.created
event. This webhook will be triggered whenever a new user signs up and authenticates with Clerk. Using this webhook, we can automatically add a User record to our PlanetScale database, storing the user’s unique ID and email address.
In the next section, I’ll guide you through the steps I took to develop a Clerk webhook that adds a User record to the database whenever someone authenticates with Clerk. This will give you an understanding of how to create a webhook in your projects and make the most of Clerk’s webhook capabilities.
1. The Libraries
To begin, we’ll create a webhook endpoint in our Next.js application to handle incoming webhook requests from Clerk. This endpoint will be responsible for processing the user.created
event and adding the User record to our database.
First, create a new file called clerk-webhook.ts
in the pages/api
directory of your Next.js project. This file will contain our webhook handler.
Next, we’ll import the necessary libraries and dependencies to set up the webhook:
Here’s a brief explanation of each imported module:
NextApiRequest
andNextApiResponse
: Types from Next.js for handling API requests and responses.PrismaClient
: The Prisma client, which allows us to interact with our database.User
,UserJSON
: Classes and types from Clerk’s SDK for handling user data.IncomingHttpHeaders
,WebhookRequiredHeaders
: Types for handling HTTP headers related to the webhook.Webhook
: The main class from Svix for managing and verifying webhook events.buffer
: A helper function from the micro library to read the raw request payload.env
: A custom module for accessing environment variables in our project.
Next, we’ll configure the webhook and write the handler function.
2. The Handler
Now that we have our webhook endpoint, we’ll configure the webhook and write the main handler function. First, we’ll disable the Next.js bodyParser
middleware to allow us to validate the webhook signature manually:
Let’s create a main handler function that processes the incoming webhook:
Read the raw request payload and headers.
Create a new
Webhook
instance and verify the incoming webhook request using the webhook secret.Check if the webhook event type is
user.created
.If the event is
user.created
, parse the user data from the event payload, and ensure the user has a valid email address.Create a new user record in our database using the parsed user data.
Here’s the code for the entire handler function. I created this with Carbon to make it more readable:
3. The Types
In the next step, we’ll define the necessary TypeScript types to ensure type safety in our handler function. We’ll define the following types:
NextApiRequestWithSvixRequiredHeaders
: This type extends the Next.jsNextApiRequest
type with the required headers for webhook verification.Event
: This type represents the webhook event, containing the event data, object, and type.EventType
: This type is a union of possible event types, such as “user.created” and “user.updated” when I want to support it in the future.
Here’s the code for defining these types:
With these types defined, our webhook handler function is complete, and we can successfully handle incoming webhook events from Clerk. Whenever a user authenticates with Clerk, our webhook will be triggered, and a new user record will be added to our database.
That’s it! You’ve successfully set up a Clerk webhook to add a User record to your table whenever someone authenticates with Clerk. With this webhook in place, you can now efficiently manage user data in your app and leverage the power of Clerk for seamless user authentication.
Testing with ngrok!
Testing webhook integrations can be challenging as webhooks are designed to work with live endpoints. To test your Clerk webhook locally, you can use ngrok
to expose your local server to the internet.
Follow these steps to test your webhook using ngrok:
Install ngrok: Visit https://ngrok.com/ and download the appropriate version for your operating system. Follow the installation instructions provided on the website.
Run your local server: Start your Next.js development server by running
npm run dev
oryarn dev
in your terminal.Expose your local server: In a new terminal window, run the following command to expose your local server on a public URL. Replace
3000
with the port, your local server is running on, if different../ngrok http 3000
Get your public URL: You’ll see an output similar to this. Copy the
https
version of the ngrok URL.Update the webhook URL in Clerk: Go to your Clerk dashboard, navigate to the webhooks section, and update the webhook URL with the ngrok URL you just copied, appending the route for your webhook, e.g.,
https://your-ngrok-subdomain.ngrok.io/api/clerk-webhook
.Test your webhook: When you authenticate a user through Clerk, the webhook will be triggered, and you can debug and test the webhook handler locally.
Remember that ngrok URLs are temporary and will change when you restart the ngrok process. Make sure to update the webhook URL in Clerk every time you run ngrok. When you’re done testing, replace the webhook URL in Clerk with your production endpoint.
Conclusion
In conclusion, setting up a Clerk webhook to handle user authentication events and store user data in your application is an efficient and secure way to manage user records. Following the steps outlined in this blog post, you can quickly integrate Clerk webhooks into your Next.js application and ensure seamless user management. Utilizing tools like ngrok simplifies the testing process and allows you to validate the webhook integration locally. With these tools in hand, you’re well on your way to enhancing your application’s user experience and security.
My implementation was based on hobo1618’s t3-clerk-webhook repo on GitHub.
View my entire `clerk-webhook.ts` file at my Pastebin.