JWT and middleware in NodeJS
Middleware/verifyToken.js
const User = require("../models/User");
const jwt = require("jsonwebtoken");
const verifyToken = (req, res, next) => {
const authHeader = req.headers.authorization;
if (authHeader) {
const token = authHeader.split(" ")[1];
jwt.verify(token, process.env.SECRET, async (err, user) => {
if (err) {
console.error("Error verifying token:", err);
return res.status(403).json("Invalid token");
}
req.user = user;
console.log(user);
next();
});
} else {
return res.status(401).json("You are not authenticated");
}
};
const VerifyAndAuthorization = (req, res, next) => {
verifyToken(req, res, () => {
if (req.user.id === req.params.id) {
next();
} else {
res.status(403).json("You are restricted from performing this
operation");
}
});
};
module.exports = { verifyToken, VerifyAndAuthorization };
routes/user.js
const userController = require("../controllers/userController");
const {
VerifyAndAuthorization,
verifyToken,
} = require("../middleware/verifyToken");
const router = require("express").Router();
// Update user
router.put("/:id", VerifyAndAuthorization, userController.updateUser);
module.exports = router;
controllers/usercontroller
const User = require("../models/User");
const CryptoJS = require("crypto-js");
module.exports = {
updateUser: async (req, res) => {
if (req.body.password) {
req.body.password = CryptoJS.AES.encrypt(
req.body.password,
process.env.SECRET
).toString();
}
try {
const updateUser = await User.findByIdAndUpdate(
req.params.id,
{ $set: req.body },
{ new: true }
);
const { password, __v, createdAt, ...others } =
updateUser.toObject();
res.status(200).json(others);
} catch (error) {
console.error(error);
res.status(500).json("Internal Server Error");
}
},
};
};
Index.js
const express = require("express");
const app = express();
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const authRoute = require("./routes/auth");
const userRoute = require("./routes/user");
dotenv.config();
mongoose
.connect(process.env.MONGO_URL)
.then(() => console.log("db_connected"))
.catch((err) => {
console.log(err);
});
app.use(express.json());
app.use("/api/", authRoute);
app.use("/api/users", userRoute);
app.listen(
process.env.PORT || 5002,
console.log(
`Example app listening on port http://localhost:${process.env.PORT}`
)
);
Contollers/authcontroller
const User = require("../models/User");
const CryptoJS = require("crypto-js");
const jwt = require("jsonwebtoken");
module.exports = {
// controllers/authController.js
// ...
createUser: async (req, res) => {
const newUser = new User({
username: req.body.username,
email: req.body.email,
// CryptoJS.AES.encrypt(req.body.password, process.env.SECRET);
password: CryptoJS.AES.encrypt(
req.body.password,
process.env.SECRET
).toString(),
});
try {
const savedUser = await newUser.save();
res.status(201).json(savedUser);
} catch (error) {
res.status(500).json(error);
}
},
loginUser: async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email });
if (!user) return res.status(401).json("Wrong login details");
const decryptedPass = CryptoJS.AES.decrypt(
user.password,
process.env.SECRET
);
const decryptedPassword =
decryptedPass.toString(CryptoJS.enc.Utf8);
if (decryptedPassword !== req.body.password) {
return res.status(401).json("Wrong password");
}
// Generate a token for the logged-in user
const token = jwt.sign({ id: user._id }, process.env.SECRET);
// Exclude sensitive information from the user data
const { password, __v, createdAt, ...userData } = user._doc;
// Send the user details and token in the response
res.status(200).json({ ...userData, token });
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal Server Error" });
}
},
};
.env
PORT = 5001
MONGO_URL
=mongodb+srv://samitshrestha29:[email protected]/
dbtechJOB
SECRET= jobhub2023
Models/user.js
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema(
{
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
location: { type: String, required: false },
isAdmin: { type: Boolean, default: false },
isAgent: { type: Boolean, default: false },
skills: { type: Array, default: false },
profile: {
type: String,
required: true,
default:
"https://images.pexels.com/photos/213780/pexels-photo-
213780.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
},
},
{
timestamps: true, // Fix: Correct key for the timestamps option
}
);
module.exports = mongoose.model("User", UserSchema);
index.js
const express = require("express");
const app = express();
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const authRoute = require("./routes/auth");
const userRoute = require("./routes/user");
dotenv.config();
mongoose
.connect(process.env.MONGO_URL)
.then(() => console.log("db_connected"))
.catch((err) => {
console.log(err);
});
app.use(express.json());
app.use("/api/", authRoute);
app.use("/api/users", userRoute);
app.listen(
process.env.PORT || 5002,
console.log(
`Example app listening on port http://localhost:${process.env.PORT}`
)
);
Models/Bookmark.js
const { timeStamp } = require("console");
const mongoose = require("mongoose");
const BookMarkSchema = new mongoose.Schema(
{
job: { type: String, required: true },
userId: { type: String, required: true },
title: { type: String, required: true },
imageUrl: { type: String, required: true },
company: { type: String, required: true },
location: { type: String, required: true },
},
{ timeStamp: true }
);
module.exports = mongoose.model("Bookmark", BookMarkSchema);
routes/auth.js
const router = require("express").Router();
// Correct import statement
const authController = require("../controllers/authController");
// REGISTRATION
router.post("/register", authController.createUser);
// // Login
router.post("/login", authController.loginUser);
module.exports = router;
module.exports = router;