I am trying to show the page only if the Jsonwebtoken is verified and the user is logged on to the website, else show him the sign-in page.
However, I can see the token is generated in MongoDB, and also when I console log I can see that it is all good. But the issue is when I try to verify it using an already generated jwt token i.e.
req.cookies.signinToken
it shows an error.
Please the detail code below:
On app.js
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const express = require("express");
const app = express();
const jwt = require("jsonwebtoken");
const cookieParser = require("cookie-parser");
dotenv.config({ path: "./config.env" });
require("./db/connection");
app.use(express.json());
app.use(cookieParser());
app.use(require("./router/route"));
const PORT = process.env.PORT;
app.listen(5000, () => {
console.log(`server running on ${PORT}`);
});
On route.js
const express = require("express");
const bcrypt = require("bcrypt");
const router = express.Router();
const jwt = require("jsonwebtoken");
require("../db/connection");
const User = require("../model/newUserSchema");
const auth = require("../middleware/auth");
// router.get("/", (req, res) => {
// res.send("hello am backend sever");
// });
//Signup or Register Part
router.post("/signup", async (req, res) => {
const { username, email, cpassword, retypePassword } = req.body;
if (!username || !email || !cpassword || !retypePassword) {
return res.status(422).json({ error: "please enter valid details" });
}
try {
const UserExist = await User.findOne({ email: email });
if (UserExist) {
return res.status(422).json({ error: "email already exist" });
} else if (cpassword !== retypePassword) {
return res.status(422).json({ error: "password incorrect" });
} else {
const user = new User({
username,
email,
cpassword,
retypePassword,
});
const userResgister = await user.save();
if (userResgister) {
return res.status(201).json({ message: "signup successfully" });
}
}
} catch (error) {
console.log(error);
}
});
//Login Part
router.post("/signin", async (req, res) => {
try {
const { email, cpassword } = req.body;
if (!email || !cpassword) {
return res.status(400).json({ error: " please enter valid credentials" });
}
const userLogin = await User.findOne({ email: email });
const token = userLogin.generateAuthToken();
res.cookie("signinToken", token, {
expires: new Date(Date.now() 25892000000),
httpOnly: true,
});
if (userLogin) {
const isMatch = await bcrypt.compare(cpassword, userLogin.cpassword);
if (isMatch) {
return res.status(200).json({ message: "sigin in scuccessfully" });
} else {
return res.status(400).json({ error: " Invalid credentials" });
}
} else {
return res.status(400).json({ error: " Invalid credentials " });
}
} catch (error) {
console.log(error);
}
});
//watchlistpage
router.get("/watchlist", auth, (req, res) => {
console.log(" this is jwt token test " req.cookies.signinToken);
res.send(req.rootuser);
console.log(req.rootuser);
});
module.exports = router;
On newUserSchema.js:
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const newUserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
cpassword: {
type: String,
required: true,
},
retypePassword: {
type: String,
required: true,
},
tokens: [
{
token: {
type: String,
required: true,
},
},
],
});
newUserSchema.pre("save", async function (next) {
if (this.isModified("cpassword")) {
this.cpassword = await bcrypt.hash(this.cpassword, 12);
this.retypePassword = await bcrypt.hash(this.retypePassword, 12);
}
next();
});
newUserSchema.methods.generateAuthToken = async function () {
try {
let token = jwt.sign({ _id: this._id }, process.env.SECRETKEY);
this.tokens = this.tokens.concat({ token: token });
await this.save();
return token;
} catch (error) {
console.log(error);
}
};
const User = mongoose.model("newUser", newUserSchema);
module.exports = User;
On auth.js (this is also my middleware)
const jwt = require("jsonwebtoken");
const User = require("../model/newUserSchema");
const Auth = async (req, res, next) => {
try {
console.log(JSON.stringify(req.cookies.signinToken) " this is jwt token test");
const token = req.cookies.signinToken;
const verifytoken = jwt.verify(token, process.env.SECRETKEY);
const rootuser = await User.findOne({ _id: verifytoken._id, "tokens.token": token });
if (!rootuser) {
throw new Error("user not found");
}
req.token = token;
req.rootuser = rootuser;
req.UserID = rootuser._id;
next();
} catch (error) {
res.status(401).send("Unauthorized access");
console.log(error);
}
};
module.exports = Auth;
The API call result in postman
The terminal error :
when I try to console log on route.js inside Signin page i see promise pending
const token = userLogin.generateAuthToken();
console.log(token);
res.cookie("signinToken", token, {
expires: new Date(Date.now() 25892000000),
httpOnly: true,
});
Could you please help to correct the error also please let me know why is this error coming?
Thanks a million in advance for any tips or suggestions.
CodePudding user response:
Hi Thanks for the help
I just saw that my token was returning a promise, I did not add the keyword await before the token other thing was I was trying to access it before the validation, hence it was showing me nodata and error.
Please see the correct code below:
//Login Part
router.post("/signin", async (req, res) => {
try {
const { email, cpassword } = req.body;
if (!email || !cpassword) {
return res.status(400).json({ error: " please enter valid credentials" });
}
const userLogin = await User.findOne({ email: email });
if (userLogin) {
const isMatch = await bcrypt.compare(cpassword, userLogin.cpassword);
const token = await userLogin.generateAuthToken();
console.log(token);
res.cookie("signinToken", token, {
expires: new Date(Date.now() 25892000000),
httpOnly: true,
});
if (isMatch) {
return res.status(200).json({ message: "sigin in scuccessfully" });
} else {
return res.status(400).json({ error: " Invalid credentials" });
}
} else {
return res.status(400).json({ error: " Invalid credentials " });
}
} catch (error) {
console.log(error);
}
});
I hope this might help other learners too.
Thanks.