Implementing NextAuth with NextJS and MongoDB: A Step-by-Step Guide

Read time: 3 minutes

User Profile

Wali Ullah

May 18, Sat

In this guide, we will walk through the process of implementing NextAuth with Next.js 14 and storing users in MongoDB in just 7 easy steps.

1. Create a NextJS app

create-next-app@14

2. Install NextAuth by running

npm install next-auth

3. Install bcrypt to hash passwords and Mongoose to store user data in MongoDB:

npm install mongoose bcrypt

4. Create a database connection:

​Create a db.js file inside your libs folder and add the following code:

import mongoose from "mongoose";

const url = process.env?.MONGODB_URI;
let connection;

const startDbConnection = async () => {
if (!connection) {
connection = await mongoose.connect(url);
console.log("Connected to Database");
}
return connection;
};

export default startDbConnection;

Create User Model

import { Model, models, model } from "mongoose";
import { Schema } from "mongoose";
import bcrypt from "bcrypt";

const userSchema = new Schema({
    email: { type: String, required: true, unique: true },
    name: { type: String, required: true, trim: true },
    password: { type: String, required: true },
    role: { type: String, default: "user" }
});

// hash the password before saving
userSchema.pre("save", async function (next) {
    if (!this.isModified("password")) return next();
    try {
        const salt = await bcrypt.genSalt(10);
        this.password = await bcrypt.hash(this.password, salt);
        next();
    } catch (error) {
      throw error;
    }
});

// compare password method
userSchema.methods.comparePassword = async function (password) {
    try {
      return await bcrypt.compare(password, this.password);
    } catch (error) {
     throw error;
    }
};

const UserModal = models.User || model("User", userSchema);

export default UserModal;


To authenticate users with NextAuth, you need to store user data in the database first. Since adding the signup route would make the blog longer, we will focus solely on NextAuth.


Assuming you already have a simple signup API route set up where you store user data in the database. Let's proceed to the final steps.


5. Create a route for API

Now Navigate to the app folder and create an API route file in the directory/api/auth/[...nextauth]/route.js


6. Write the below code for authentication with NextAuth.

import startDbConnection from "@/libs/db";
import UserModel from "@/models/userModel";
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";


export const authOptions = {
  session: {
  strategy: "jwt",
},
providers: [
    CredentialsProvider({
    type: "credentials",
    credentials: {},
    async authorize(credentials, req) {
     const { email, password } = credentials;
     await startDbConnection();

     const user = await UserModel.findOne({ email });
     if (!user) throw Error("Email or password incorrect!");

      const passwordMatch = await user.comparePassword(password);
     if (!passwordMatch) throw Error("Email or password incorrect!");

     return {
        name: user.name,
        email: user.name,
        role: user.role,
        id: user._id
     };
    },    
  }),
],
callbacks: {
jwt(params) {
if (params.user?.role) {
     params.token.role = params.user.role;
     params.token.id = params.user.id;
    }
    return params.token;
  },
session({ session, token }) {
    if (session.user) {
     session.user.id = token.id;
     session.user.role = token.role;
    }
    return session;
    },
  },
};


const authHandler = NextAuth(authOptions);
export { authHandler as GET, authHandler as POST };


7. Create a simple login component and render it inside the page.

Ensure you have added the use client keyword at the top of your login component if you are using NextJS app router.

Assuming you have set up the form and handle inputs, here is the function you need for submitting the form.


import { signIn } from "next-auth/react";
import API from "@/utils/api";

const handleSubmit = async (e) => {
    e.preventDefault();
    const { email, password } = userInfo;

    setLoading(true);
    try {
     const res = await signIn("credentials", {
     email, password, redirect: false,
    });
    setLoading(false);

    if (res?.error) return alert(res?.error);
    setUserInfo({ email: "", password: ""});

    } catch (error) {
     console.log(error);
     setLoading(false);
    }
};


That's it.

By following these 7 steps, you can implement NextAuth with NextJS 14 efficiently.

Interested in Publishing your knowledge and sharing it with the world?

Or ask anything about our services

We thrive by partering with visionary brands and driven individuals.

Say hello 👋

[email protected]