Implementing NextAuth with NextJS and MongoDB: A Step-by-Step Guide
Read time: 3 minutes
Wali Ullah
May 18, Sat
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:
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;
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.
You may also like
Microservices Architecture
Interested in Publishing your knowledge and sharing it with the world?
We thrive by partering with visionary brands and driven individuals.
Say hello 👋