Using an ID/Password + JWT

Posted by : on

Category : next


Reference


Using an ID/Password + JWT

Next.js version

"next": "13.2.4”

Setting up the library

npm install bcrypt


If you want to log in using the username/password method

You can do this by selecting the Credentials provider in the Next-auth library settings.

However, in this case, we are forced to use the JWT method instead of the session method.

Let’s start by creating a signup page and functionality.

  1. On the signup page, when the user submits their username/password to the server, the
  2. The server stores it in the DB

Let’s implement it as is.


1. When the user submits their username/password on the signup page, the


(app/register/page.js)

export default function Register() {
  return (
    <div>
      <form method="POST" action="/api/auth/signup">
        <input name="name" type="text" placeholder="Name" />
        <input name="email" type="text" placeholder="E-mail" />
        <input name="password" type="password" placeholder="PW" />
        <button type="submit">Request</button>
      </form>
    </div>
  );
}

The reason I left out id and only put email is because I wanted to use the

When I log in with OAuth, I don’t see a username, only an email.

Writing emails also serves a sort of consistency purpose.


2. The server stores it in the DB


We want to store the password encrypted in the DB, so we install the encryption library bcrypt.

(pages/api/auth/signup.js)

import bcrypt from "bcrypt";
import { connectDB } from "util/database";

export default async function handler(req, res) {
  if (req.method === "POST") {
    let { name, email, password } = req.body;
    if (!name || !email || !password) {
      return res.status(400).json("Spaces are not allowed.");
    }
    let db = (await connectDB).db("forum");
    const compareDB = await db
      .collection("user_cred")
      .findOne({ email: email });
    if (compareDB) {
      return res.status(400).json("An account that already exists.");
    }
    const hash = await bcrypt.hash(password, 10);
    password = hash;
    await db.collection("user_cred").insertOne({
      name,
      email,
      password,
      role: "user",
    });
    res.status(200).json("Sucess!");
  } else {
    res.status(400).json("This is an incorrect approach.");
  }
}

(1) Put your password in bcrypt.hash and it will encrypt it. 10 is the encryption level, but you can modify it as you like

(2) Then I told it to create the user information as an object and put it in the user_cred collection.


Set up a credentials provider


If you also set the Credentials provider in the Next-auth setting, you can log in with your username/password.

import NextAuth from "next-auth";
import GithubProvider from "next-auth/providers/github";
import { MongoDBAdapter } from "@next-auth/mongodb-adapter";
import { connectDB } from "util/database";
import CredentialsProvider from "next-auth/providers/credentials";
import bcrypt from "bcrypt";

export const authOptions = {
  providers: [
    GithubProvider({
      clientId: process.env.CLIENT_ID,
      clientSecret: process.env.CLIENT_PW,
    }),
    CredentialsProvider({
      //1. Code to automatically generate a login page form
      name: "credentials",
      credentials: {
        email: { label: "email", type: "text" },
        password: { label: "password", type: "password" },
      },

      //2. Code executed on login request
      //Compare IDs and passwords directly from the DB and use the
      //Should return result if id and password are correct, return null if incorrect
      async authorize(credentials) {
        let db = (await connectDB).db("forum");
        let user = await db
          .collection("user_cred")
          .findOne({ email: credentials.email });
        if (!user) {
          console.log("No such emails");
          return null;
        }
        const pwcheck = await bcrypt.compare(
          credentials.password,
          user.password
        );
        if (!pwcheck) {
          console.log("Wrong pw");
          return null;
        }
        return user;
      },
    }),
  ],

  //3. Write a JWT to make it work + Set a JWT expiration date
  session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60, //30day
  },

  callbacks: {
    //4. Code executed when creating a JWT
    //The user variable contains the user information of the DB, and if you store something in token.user, it will be entered into the jwt.
    jwt: async ({ token, user }) => {
      if (user) {
        token.user = {};
        token.user.name = user.name;
        token.user.email = user.email;
        token.user.role = user.role;
      }
      return token;
    },
    //5. Code that runs every time a user session is looked up
    session: async ({ session, token }) => {
      session.user = token.user;
      return session;
    },
  },

  secret: process.env.JWT_SECRET,
  adapter: MongoDBAdapter(connectDB),
};
export default NextAuth(authOptions);

You don’t need to memorize and study the library usage, you can just copy and paste it.

The most important thing is number 2.

You need to compare the login ID/password with the contents stored in the DB.

Let’s modify it to suit your DB situation.


About George
George

I'm George, a Web Developer.

Email : kghee9612@gmail.com

Website : https://ge5rg2.github.io

About George

Hi, my name is George. This is where I record what I have studied :D

Star
Useful Links