Using NextAuth.js with Bison

August 19, 2021

Kishan Gajera

Bison is a starter template for building Next.js web applications that we use for our clients at Echobind. Out of the box, Bison rolls its own username and password authentication implementation. One of the great things about Bison, is that you can easily swap out any of the default technology choices if you don’t agree with it or if it’s not right for the job. In this post, we will replace the default authentication with NextAuth.js.

Full source code for this example can be found here:

Create a Bison App

Let’s create a new Bison app by running:

You should see the following output:

Next, we need to run the following commands to initialize the database and start the dev server:

In your web browser, we should now see the initial starting point of a Bison app:

From the screenshot above, you can see there’s already a “Login” button that will take you through the default authentication flow provided by Bison. We’ll be replacing that functionality so let’s refactor out the default authentication code that will no longer be used. The following files can be deleted:

Integrating NextAuth.js

NextAuth.js supports many different authentication providers such as Google, Facebook, etc. In this example, we will be using the email provider which will send a “magic link” to your email to sign in.

Install Dependencies

First, let’s install the dependency:

While creating the Bison app, you probably noticed it requires a Postgres database and uses prisma as the ORM. So we need to install the appropriate adapter for NextAuth.js so it knows how to persist data in our database:

Updating the Prisma Schema

NextAuth.js requires the following schema to save users and authentication-related data such as sessions, providers, and verification requests.

After you’ve updated the prisma schema, run the following command to generate the prisma client:

Configuring NextAuth.js

We will create a new file, pages/api/auth/[..nextauth].ts, to configure the email provider and prisma database adapter.

You’ll notice there are a couple of environment variables for sending emails that need to be added. At Echobind, SendGrid is our go-to email service. We won’t go in-depth about email services in this post, but after creating a SendGrid account, verifying a domain or specific email address, and creating an API key, you can start sending emails.

Checking For Authenticated User Client Side

Bison uses a different “layout” component depending on whether a user is logged in or not. This is controlled in pages/_app.tsx. To determine if a user is logged in, we will use the useSession() react hook provided by NextAuth.js.

We also need to update the click handler for the “Login” and “Logout” buttons to use the new sign-in flow by updating them to call the and methods respectively from NextAuth.js.

In , we can update the "Login" button to have the following handler:

Now, if we click the login button, it should navigate to the default login form provided by NextAuth.js:

When the form is submitted, it will send the following email containing the “magic link” to the email address that was entered:

In , we can update the "Logout" button to have the following handler:

Checking For Authenticated User Server Side

Bison uses a GraphQL API. For each request, using the session, we need to query for the user and set it in the context object that will be passed to the GraphQL resolvers.

Additional Resources

Want to learn more about NextAuth.js? Check out Mike Cavaliere’s three-part series starting with NextAuth.js Intro [1 of 3]: One-Click Signup.

Do you have opinions for or against using NextAuth.js as the default authentication included in the Bison template? Upvote or leave a comment in our GitHub discussion.

More about:

Kishan Gajera

Kishan Gajera is a Senior Software Engineer with over 10 years of experience building web and mobile applications. He is passionate about building maintainable solutions as well as improving developer experience and productivity. Outside of work, his interests are basketball, fitness, and spending time with his family.