In this post, I talk about how to set up credentials authentication with HarperDB, Hono and Vercel. We learn how to setup our HarperDB instance, configure credentials authentication helpers for HarperDB, create Hono Endpoints to sign up, sign in and create custom sessions for the users in a given app.
Tech Stack
Prerequisites
- Node.js 18
- A HarperDB account
- A Vercel account
Setting up the project
To set up, just clone the app repo and follow this tutorial to learn everything that's in it. To fork the project, run:
Once you have cloned the repo, you are going to create a .env file. You are going to add the values we obtain from the steps below.
Setting up HarperDB
Let’s start by creating our database instance. Sign in to Harper Studio and click on Create New HarperDB Cloud Instance.
Fill in the database instance information, like here, we’ve added credentialsauth as the instance name with a username and password.
Go with the default instance setup for RAM and Storage Size while optimizing the Instance Region to be as close to your serverless functions region in Vercel.
After some time, you’d see the instance (here, credentialsauth) ready to have databases and its tables. The dashboard would look something like as below:
Let’s start by creating a database (here, list) inside which we’ll spin our storage table, make sure to click the check icon to successfully spin up the database.
Let’s start by creating a table (here, collection) with a hashing key (here, id) which will be the named primary key of the table. Make sure to click the check icon to successfully spin up the table.
Once done:
- Open lib/harper.ts and update the database and table values per the names given above.
- Click on config at the top right corner in the dashboard, and:
- Copy the Instance URL and save it as HARPER_DB_URL in your .env file
- Copy the Instance API Auth Header and save it as HARPER_AUTH_TOKEN in your .env file
Awesome, you’re good to go.
Configuring Credentials Authentication helpers for HarperDB for Vercel Edge and Middleware Compatibility
To interact with the HarperDB database, we’ll use HarperDB Security REST APIs called over fetch. This approach will help us opt out of any specific runtime requirements, and keep things simple and ready to deploy to Vercel Edge and Middleware.
Let’s create a global harperFetch function which will abstract the fetch related code from our Credentials Authentication helpers 👇🏻
Creating User Roles in HarperDB Instance
When creating a new, user-defined role in a HarperDB instance, one needs to provide a role name and the permissions to assign to that role. As we just require to authenticate users for our app, and not actually require authentication to read/write values from/to database, we’ll restrict all kind of permissions to a specific table in a HarperDB instance.
The role, table name, and associated permissions are configured through the function parameters of addRole, and the response includes the assigned role's unique identifier.
HarperDB takes care of ensuring that a specific role is created only once. Hence, even if the endpoint is called multiple times with the same field values, HarperDB would return error messages to indicate database conflicts.
Sign Up Users via HarperDB
To let user sign up into our app, we’d use the add_user HarperDB operation to create a new user in the HarperDB instance, specifying the username, password, role, and optional active status. The response includes a message attribute indicating the success of the user creation process.
HarperDB takes care of implementing user credentials collisions and enforce value validations. This allows you to effortlessly pass on the username and password for signing up users without validating the field values on your own.
Sign In Users via HarperDB
To let user sign in into our app, we’d use the create_authentication_tokens HarperDB operation to create tokens via the HarperDB instance, specifying the username and password of the user. A successful response includes an operation_token attribute indicating the correct credentials of the user.
With HarperDB, the create_authentication_tokens operation can be used at any time to refresh the operation_token in the event that it expired or was lost.
Set up Hono with Vercel Edge
Let's kick things off by setting up a Hono app with the Vercel template. It’s pretty similar to creating an Express app 👇🏻
Now, let’s configure Hono endpoints for each operation i.e. to sign up, sign in and create custom sessions for the users 👇🏻
An Endpoint To Create User Roles Dynamically
We’ll establish an endpoint responsible for dynamically creating user roles in HarperDB. The route /create/user/roles expects a JSON payload containing roleName and tableName, validates the input fields, and utilizes the addRole function we created earlier to add the specified role with associated permissions to the designated table.
Below a sample response from this particular endpoint 👇
An Endpoint To Sign Up Users
We’ll establish an endpoint responsible for user sign-ups in HarperDB through the createUser function we created earlier. The route /create/user expects a JSON payload containing username, password, and roleName. It performs input validation, and creates a new user with the specified credentials. Upon successful user creation, it extracts the operation token and, if applicable, any error messages. Additionally, we set a signed cookie (custom_auth) with server-side operations and secure configurations for authentication.
Below a sample response from this particular endpoint 👇
An Endpoint To Sign In Users
We’ll establish an endpoint responsible for signing in users via HarperDB. The route /get/user expects a JSON payload containing username and password. It validates the input fields and utilizes the getUser function we created earlier to authenticate the user. Upon successful authentication, it extracts the operation token and, if applicable, any error messages. The code concludes by setting a signed cookie (custom_auth).
Below a sample response from this particular endpoint 👇
An Endpoint To Get User Details
We’ll establish an endpoint to retrieve user details on the server-side. Utilizing the getSignedCookie method from hono/cookie and the getEnv function we created earlier, the route /get/session obtains a signed cookie (custom_auth) based on the server-side secret. If the cookie is present, it extracts the operation token of the logged-in user and returns a sanitized user object, excluding sensitive fields like operation_token and refresh_token. If no login is found, the endpoint responds with an error message.
Below a sample response from this particular endpoint 👇
Whew! All done, let's deploy our Hono app to Vercel 👇
Deploy to Vercel
The repository is ready to deploy to Vercel. Follow the steps below to deploy seamlessly 👇🏻
- Create a GitHub Repository with the app code
- Create a New Project in Vercel Dashboard
- Link the created GitHub Repository as your new project
- Scroll down and update the Environment Variables from the .env locally
- Deploy! 🚀
References
Demo: https://harperdb-hono-vercel-credentials-auth.vercel.app/
GitHub Repo: https://github.com/rishi-raj-jain/harperdb-hono-vercel-credentials-auth
JWT Authentication: https://docs.harperdb.io/docs/developers/security/jwt-auth
HarperDB Users & Roles: https://docs.harperdb.io/docs/developers/security/users-and-roles
HarperDB Basic Authentication: https://docs.harperdb.io/docs/developers/security/basic-auth
Hono Web Framework: https://hono.dev