Create an Authentication System with Node JS and MongoDB Part 2
In the second part of this tutorial, we will create the routes, add the middleware and finally register and log in the users.
Create the JWT Secret
Inside the file 'config.js' let's add the JWT Secret we will use it later when creating the token.
export const JWT_SECRET = "ABCDEFJHIJKLMNOPQRSTUVWXYZ";
Create the middleware
Next, let's create a new folder 'middleware' Inside add a new file 'authMiddleware.js' Inside add the code below:
import jwt from "jsonwebtoken";
import { JWT_SECRET } from '../config.js';
export const auth = async (req, res, next) => {
try {
// get the token from the header
const token = await req.headers.authorization.split(" ")[1];
//check if the tokens matches
const decodedToken = await jwt.verify(token, JWT_SECRET);
// retrieve the logged in user
const user = await decodedToken;
// pass the user to the route
req.user = user;
// move to the next
next();
} catch (error) {
return res.status(401).json({
error: "Unauthenticated",
});
}
};
Create the route
Inside the backend folder create a new folder 'routes' Inside create a new file 'userRouter.js' and add the code below inside.
import express from 'express';
import User from '../models/userModel.js';
import jwt from 'jsonwebtoken';
import { JWT_SECRET } from '../config.js';
import bcrypt from 'bcryptjs';
import { auth } from '../middleware/authMiddleware.js';
const userRouter = express.Router();
userRouter.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
if(!email || !password) {
return res.status(422).send({
error: "All the fields are required"
});
}else {
const user = await User.findOne({email});
if (user) {
const passwordCheck = await bcrypt.compare(password, user.password);
// check if password matches
if(!passwordCheck) {
return res.status(400).send({
error: "Invalid email or password"
});
}else {
//create the token
const token = jwt.sign({
userId: user._id
}, JWT_SECRET , { expiresIn: '10d'});
return res.status(200).send({
user: {
_id: user._id,
username: user.username,
email: user.email
},
token
});
}
}else {
return res.status(500).send({
error: "Invalid email or password"
});
}
}
} catch (error) {
return res.status(500).send({
error: error.message
});
}
});
userRouter.post("/register", async (req, res) => {
const { username, email, password } = req.body;
if(!username || !email || !password) {
return res.status(422).send({
error: "All the fields are required"
});
}
try {
const exists = await User.findOne({email});
//check if user already exists
if (exists) {
return res.status(422).send({
error: "Email already taken",
});
}
// hash the password
const hashedPassword = await bcrypt.hash(password, 10);
// create a new user instance and collect the data
const user = new User({
username: username,
email: email,
password: hashedPassword
});
// save the new user
const createdUser = await user.save();
if(createdUser) {
return res.status(200).send({
message: "User Created Successfully",
});
}else {
return res.status(500).send({
error: "Error creating user"
});
}
} catch (error) {
return res.status(500).send({
error
});
}
});
// get logged in user
userRouter.get("/user", auth, async (req, res) => {
const user = await User.findById(req.user.userId);
return res.status(200).send({
user
});
});
export default userRouter;
Use the route
Finally, let's import and use the route inside the index.js file.
import { db } from "./config.js";
import express from "express";
import cors from "cors";
import mongoose from "mongoose";
import userRouter from './routes/userRouter.js';
const app = express();
app.use(express.json());
app.use(cors());
app.use('/users', userRouter);
//connect to the database
mongoose.connect(db).then(() => {
app.listen(3001, () => {
console.log('App is running on port 3001');
});
}).catch(error => console.log(error));