Node.js API Authentication with JWT (Json Web Token) – Auth Middleware

Hi, Today we are going to implement API authentication with JWT in node.js application. Authentication is most important feature in every application. Even if you are beginner feel free to try this tutorial, we gonna start from scratch. We also gonna w…

Hi, Today we are going to implement API authentication with JWT in node.js application. Authentication is most important feature in every application. Even if you are beginner feel free to try this tutorial, we gonna start from scratch. We also gonna write Auth middleware, which allow only authenticated people to access the route.

For better understanding watch Demo Video


Source Code

Let’s Start Coding…

App Overview :

Project Structure
Project_structure
Following table shows the overview of the Rest APIs that be exported :

Methods Urls Actions
POST /api/users Create user
POST /api/auth Authenticate user
GET /api/users/me Get authenticated user details

Create Node.js App and Install dependencies

$    mkdir node-auth-jwt
$    cd node-auth-jwt
$    npm init --yes
$    npm install express mongoose jsonwebtoken bcrypt joi dotenv

express : Express is minimal and flexible Node.js web applicaton framework.
mongoose : Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js.
jsonwebtoken : It’s a compact URL of representing claims to be transferred between two parties.
bcrypt : It’s a password hashing function.
joi : Joi is an object schema description language and validator for javascript objects.
dotenv : It loads environment variables from a .env file.

Setup Express Web Server
/index.js

require("dotenv").config();
const express = require("express");
const app = express();

app.use(express.json());

const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`Listening on port ${port}...`));

Configure Environmental Variables
/.env

DB = "mongodb://localhost/node-auth-api/"
JWTPRIVATEKEY = "secretkey"
SALT = 10

Configure MongoDB Database
/db.js

const mongoose = require("mongoose");

module.exports = async () => {
    try {
        const connectionParams = {
            useNewUrlParser: true,
            useUnifiedTopology: true,
            useCreateIndex: true,
        };
        await mongoose.connect(process.env.DB, connectionParams);
        console.log("connected to database.");
    } catch (error) {
        console.log("could not connect to database", error);
    }
};

Import db.js in index.js and call it

//...
const connection = require("./db");
const express = require("express");
const app = express();

connection();
app.use(express.json());
//...

Create User Model
/models/user.js

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const jwt = require("jsonwebtoken");
const Joi = require("joi");

const userSchema = new Schema({
    name: {
        type: String,
        required: true,
    },
    email: {
        type: String,
        required: true,
    },
    password: {
        type: String,
        required: true,
    },
});

userSchema.methods.generateAuthToken = function () {
    const token = jwt.sign({ _id: this._id }, process.env.JWTPRIVATEKEY);
    return token;
};

const User = mongoose.model("user", userSchema);

const validate = (user) => {
    const schema = Joi.object({
        name: Joi.string().required(),
        email: Joi.string().email().required(),
        password: Joi.string().required(),
    });
    return schema.validate(user);
};

module.exports = { User, validate };

What we have done :

  • We have created user table with name, email and password.
  • With JWT, we generate token with payload of user id.
  • With Joi, we gonna validate data.

Register Route
/routes/users.js

const { User, validate } = require("../models/user");
const bcrypt = require("bcrypt");
const express = require("express");
const router = express.Router();

router.post("/", async (req, res) => {
    try {
        const { error } = validate(req.body);
        if (error) return res.status(400).send(error.details[0].message);

        const user = new User(req.body);

        const salt = await bcrypt.genSalt(Number(process.env.SALT));
        user.password = await bcrypt.hash(user.password, salt);
        await user.save();

        res.send(user);
    } catch (error) {
        console.log(error);
        res.send("An error occured");
    }
});

module.exports = router;

Login Route
/routes/auth.js

const { User } = require("../models/user");
const bcrypt = require("bcrypt");
const Joi = require("joi");
const express = require("express");
const router = express.Router();

router.post("/", async (req, res) => {
    try {
        const { error } = validate(req.body);
        if (error) return res.status(400).send(error.details[0].message);

        const user = await User.findOne({ email: req.body.email });
        if (!user) return res.status(400).send("Invalid email or password");

        const validPassword = await bcrypt.compare(
            req.body.password,
            user.password
        );
        if (!validPassword)
            return res.status(400).send("Invalid email or password");

        const token = user.generateAuthToken();
        res.send(token);
    } catch (error) {
        console.log(error);
        res.send("An error occured");
    }
});

const validate = (user) => {
    const schema = Joi.object({
        email: Joi.string().email().required(),
        password: Joi.string().required(),
    });
    return schema.validate(user);
};

module.exports = router;

Auth Middleware
/middleware/auth.js

const jwt = require("jsonwebtoken");

module.exports = (req, res, next) => {
    try {
        const token = req.header("x-auth-token");
        if (!token) return res.status(403).send("Access denied.");

        const decoded = jwt.verify(token, process.env.JWTPRIVATEKEY);
        req.user = decoded;
        next();
    } catch (error) {
        res.status(400).send("Invalid token");
    }
};

User Get Route
/routes/users.js

const auth = require("../middleware/auth");
//...

router.get("/me", auth, async (req, res) => {
    try {
        const user = await User.findById(req.user._id).select("-password -__v");
        res.send(user);
    } catch (error) {
        console.log(error);
        res.send("An error occured");
    }
});

module.exports = router;

Import Routes in Index.js

//...
const users = require("./routes/users");
const auth = require("./routes/auth");
//...

app.use(express.json());

app.use("/api/users", users);
app.use("/api/auth", auth);

//...

That’s it Run the server and test the APIs. If you found any mistakes or making code better please let me know in comment. I hope you have learned something.

Thank you…


Print Share Comment Cite Upload Translate
APA
Jahangeer | Sciencx (2024-04-18T15:55:15+00:00) » Node.js API Authentication with JWT (Json Web Token) – Auth Middleware. Retrieved from https://www.scien.cx/2021/06/04/node-js-api-authentication-with-jwt-json-web-token-auth-middleware/.
MLA
" » Node.js API Authentication with JWT (Json Web Token) – Auth Middleware." Jahangeer | Sciencx - Friday June 4, 2021, https://www.scien.cx/2021/06/04/node-js-api-authentication-with-jwt-json-web-token-auth-middleware/
HARVARD
Jahangeer | Sciencx Friday June 4, 2021 » Node.js API Authentication with JWT (Json Web Token) – Auth Middleware., viewed 2024-04-18T15:55:15+00:00,<https://www.scien.cx/2021/06/04/node-js-api-authentication-with-jwt-json-web-token-auth-middleware/>
VANCOUVER
Jahangeer | Sciencx - » Node.js API Authentication with JWT (Json Web Token) – Auth Middleware. [Internet]. [Accessed 2024-04-18T15:55:15+00:00]. Available from: https://www.scien.cx/2021/06/04/node-js-api-authentication-with-jwt-json-web-token-auth-middleware/
CHICAGO
" » Node.js API Authentication with JWT (Json Web Token) – Auth Middleware." Jahangeer | Sciencx - Accessed 2024-04-18T15:55:15+00:00. https://www.scien.cx/2021/06/04/node-js-api-authentication-with-jwt-json-web-token-auth-middleware/
IEEE
" » Node.js API Authentication with JWT (Json Web Token) – Auth Middleware." Jahangeer | Sciencx [Online]. Available: https://www.scien.cx/2021/06/04/node-js-api-authentication-with-jwt-json-web-token-auth-middleware/. [Accessed: 2024-04-18T15:55:15+00:00]
rf:citation
» Node.js API Authentication with JWT (Json Web Token) – Auth Middleware | Jahangeer | Sciencx | https://www.scien.cx/2021/06/04/node-js-api-authentication-with-jwt-json-web-token-auth-middleware/ | 2024-04-18T15:55:15+00:00
https://github.com/addpipe/simple-recorderjs-demo