Next.js
MongoDB Login & Sign Up Next.js

MongoDB Login with Next.js Documentation

This documentation explains the code for implementing MongoDB-based user authentication in a Next.js application.

Introduction

This code is a Next.js API route that handles user login using MongoDB as the database. It validates the user's credentials and sets a session cookie upon successful login.

Dependencies

  • Cookies: This code uses the cookies library to manage cookies.
  • clientPromise: This is a MongoDB client promise used to establish a connection to the MongoDB database.
  • createHash: Imported from the node:crypto module for hashing the user's password.

SourceCode

GitHub: https://github.com/Dyplay/login-signup-nextjsv2 (opens in a new tab)

Code Explanation

Login.js

The code is structured as an asynchronous handler function that listens for HTTP POST requests. It follows these steps:

login.js
import Cookies from 'cookies'
import clientPromise from "../../lib/mongodb";
const {createHash} = require('node:crypto');
 
export default async function handler(req, res) {
  if (req.method == "POST") {
    // Handle login logic
  } else {
    // Redirect to the home page if it's not a POST request
  }
}

Extract the username and password from the request body.

login.js
const username = req.body['username'];
const guess = req.body['password'];

Establish a connection to the MongoDB database and retrieve the user's profile based on the provided username.

login.js
const client = await clientPromise;
const db = client.db("Users");
const users = await db.collection("Profiles").find({"Username": username}).toArray();

Check if a user with the given username exists. If not, redirect to the login page with an error message.

login.js
if (users.length == 0) {
  res.redirect("/login?msg=Incorrect username or password");
  return;
}

Retrieve the user's profile from the database.

login.js
const user = users[0];

Hash the provided password and compare it to the stored hashed password.

login.js
const guess_hash = createHash('sha256').update(guess).digest('hex');
if (guess_hash == user.Password) {
  // Successful login: Set a cookie and redirect to the home page
  const cookies = new Cookies(req, res);
  cookies.set('username', username);
  res.redirect("/");
} else {
  // Incorrect password: Redirect to the login page with an error message
  res.redirect("/login?msg=Incorrect username or password");
}

If the request method is not POST, redirect to the home page.

login.js
} else {
  res.redirect("/");
}

Signup.js

The code is structured as an asynchronous handler function that listens for HTTP POST requests. It follows these steps:

signup.js
import Cookies from 'cookies'
import clientPromise from "../../lib/mongodb";
const {createHash} = require('node:crypto');
 
export default async function handler(req, res) {
  if (req.method == "POST") {
    // Handle registration logic
  } else {
    // Redirect to the home page if it's not a POST request
  }
}

Check if the HTTP request method is POST.

signup.js
if (req.method == "POST") {
  // Handle registration logic
} else {
  // Redirect to the home page if it's not a POST request
}

Extract the username, password, and passwordagain from the request body.

signup.js
const username = req.body['username'];
const password = req.body['password'];
const passwordagain = req.body['passwordagain'];

Check if the password matches the passwordagain. If not, redirect to the sign-up page with an error message.

signup.js
if (password != passwordagain) {
  res.redirect("/signup?msg=The two passwords don't match");
  return;
}

Establish a connection to the MongoDB database and check if a user with the provided username already exists.

signup.js
const client = await clientPromise;
const db = client.db("Users");
const users = await db.collection("Profiles").find({"Username": username}).toArray();

If a user with the same username already exists, redirect to the sign-up page with an error message.

signup.js
if (users.length > 0) {
  res.redirect("/signup?msg=A user already has this username");
  return;
}

Hash the provided password and store the user's information in the database, including the current date.

signup.js
const password_hash = createHash('sha256').update(password).digest('hex');
const currentDate = new Date().toUTCString();
const bodyObject = {
    Username: username,
    Password: password_hash,
    Created: currentDate
}
await db.collection("Profiles").insertOne(bodyObject);

Set a session cookie with the username and redirect to the home page upon successful registration.

signup.js
const cookies = new Cookies(req, res)
cookies.set('username', username)
res.redirect("/")

If the request method is not POST, redirect to the home page.

signup.js
} else {
  res.redirect("/");
}

Logout.js

The code is structured as an asynchronous handler function that listens for HTTP GET requests. It follows these steps:

logout.js
import Cookies from 'cookies'
 
export default async function handler(req, res) {
  if (req.method == "GET") {
    // Handle logout logic
  } else {
    // Redirect to the home page if it's not a GET request
  }
}

Check if the HTTP request method is GET.

logout.js
if (req.method == "GET") {
  // Handle logout logic
} else {
  // Redirect to the home page if it's not a GET request
}

Create a new Cookies instance to manage cookies.

logout.js
const cookies = new Cookies(req, res)

Clear the session cookie by calling cookies.set('username') without providing a value. This effectively removes the username cookie.

logout.js
cookies.set('username')

Redirect the user to the home page after successfully logging out.

logout.js
res.redirect("/")

If the request method is not GET, redirect to the home page.

logout.js
} else {
  res.redirect("/");
}