Using NextAuth v5 credentials provider with database

In this post we'll be detailing the setup of NextAuth v5 for user authentication with email and password using Prisma for database operations and the credentials provider. We'll also see how to access the session and allow users to sign out.

You can read the full tutorial from this link.

The credentials provider in NextAuth is a built-in authentication provider that allows users to authenticate using email and password credentials. It's particularly useful for applications that require simple username/password authentication without relying on external identity providers like Google or Facebook. Here is how it works:

  1. Submission of Credentials: When a user submits their email and password credentials through a login form, these credentials are sent to the server for authentication.

  2. Authorization Function: The credentials provider in NextAuth employs an authorization function, which is responsible for validating the submitted credentials and authenticating the user.

  3. Validation: Before attempting to authenticate the user, the submitted credentials are typically validated against a predefined schema to ensure they meet certain criteria, such as proper email format, password length, etc.

  4. Authentication: Once the credentials are validated, the authorization function checks if a user with the provided email exists in the database. If a user is found, it compares the hashed password stored in the database with the hashed password submitted by the user. If the passwords match, the user is successfully authenticated.

  5. Handling Authentication Results: Depending on the outcome of the authentication process, the authorization function returns either the authenticated user object or null to indicate authentication failure.

Setting up NextAuth v5

To begin, we need to install the NextAuth v5 beta package:

npm install next-auth@beta

Generate an authentication secret using the following command:

npx auth secret

This will create an authentication secret, which should be copied into your .env file for security.

Create a file named auth.config.ts in the root folder of your project and add the following code:

import type { NextAuthConfig } from "next-auth";
import credentials from "next-auth/providers/credentials";
import { LoginSchema } from "./schemas";
import prisma from "@/lib/db";
import bcrypt from "bcryptjs";

export default {
  providers: [
      async authorize(credentials) {
        const validatedFields = LoginSchema.safeParse(credentials);

        if (validatedFields.success) {
          const { email, password } =;

          const user = await prisma.user.findUnique({ where: { email } });

          if (!user || !user.password) return null;

          const passwordsMatch = await, user.password);
          if (passwordsMatch) return user;

        return null;
} as NextAuthConfig;

This configuration sets up NextAuth with a custom credentials provider for authentication. Here's a detailed breakdown:

  • Import Statements: Import necessary dependencies including NextAuthConfig, the built-in credentials provider, login schema (LoginSchema), Prisma client (prisma), and bcrypt for password hashing.
  • Configuration Object: The default export is an object containing configuration options for NextAuth.
    • providers: An array specifying the authentication providers to use. Here, it includes a custom credentials provider.
    • Inside the credentials provider, there's an authorize function that receives submitted credentials, validates them against LoginSchema, and attempts to authenticate the user.
    • If the credentials are valid (validatedFields.success), it retrieves the user from the database using Prisma based on the provided email.
    • If a user is found and the hashed password matches the one stored in the database, the user object is returned, indicating successful authentication.
    • If any validation fails or authentication fails, null is returned, indicating authentication failure.

Next, create an auth.ts file and add the Prisma adapter, and destructure authConfig:

import NextAuth from "next-auth";
import { PrismaAdapter } from "@auth/prisma-adapter";

import authConfig from "@/auth.config";
import prisma from "@/lib/db";

export const {
  handlers: { GET, POST },
} = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" },

We also set a session configuration with a JWT strategy.

Create a route handler inside the app/api/auth/[...nextauth]/route.ts and add the following code:

export { GET, POST } from "@/auth";

Adding a Page with Sign Out

Now, let's create a page for users to sign out. Create a app/dashboard/page.tsx file and add the following code:

import { auth } from "@/auth";
import { signOut } from "@/auth";

export default async function Dashboard() {
  const session = await auth();
  return (
        onSubmit={async (e) => {
          await signOut();
        <button type="submit">Sign out</button>

In this file: - We import auth and signOut from "@/auth". - We define an asynchronous function Dashboard that returns JSX. - Inside the function, we await the auth function to get the current session data and render it as a JSON string. - We add a form with a submit button for signing out. The onSubmit handler prevents the default form submission behavior and calls signOut to sign the user out when the form is submitted.

With this setup, users can now register, sign in, and sign out of your Next.js application securely using NextAuth v5 with email and password authentication backed by Prisma for database operations.

Overall, the credentials provider in NextAuth v5 is a solution for implementing email and password authentication, offering customization options, security features, and seamless integration with database providers like Prisma. You can read the full tutorial from this link.

  • Date: