My Express.js app uses the local strategy of passport.js and passport-local-mongoose to manage authentication and sessions. In the user registration webpage, I used passport.authenticate() as a callback in User.register() when a user is created successfully. However, past
The app's code is attached below.
//#region configuration
app.use(passport.initialize());
app.use(passport.session());
const userSchema = new mongoose.Schema({ googleId: String, facebookId: String });// As passport.js will take care username and password fields if they are absent, I only created two fields manually in case I will use OAuth in the future.
userSchema.plugin(passportLocalMongoose);
const User=mongoose.model("User", userSchema);
passport.use(User.createStrategy());
passport.serializeUser((user, done)=>{
console.log(user)
done(null, user.id);
});
passport.deserializeUser((id, done)=>{
User.findOne({_id:id}, (err, user)=>{
console.log(user)
done(err, user);
});
});
//#endregion
//#region routes and handler
app.route('/register')
.get((req, res, next) => {
if(!req.user){ // if an authenticated and deserialized user is present in the session, registration doesn't occur.
res.render('auth/register', { message: req.flash('regMsg') || "" });
}else{
req.flash('regMsg', 'You are currently logged in.');
res.redirect('/contactlist');
};
})
.post((req, res, next) => {
User.register({username:req.body.useremail},req.body.password,
(err,user)=>{
if(err){
console.error("An error occurred during creating a new user.\n");
if(err.name == "UserExistsError"){
req.flash('regMsg', 'Registration Error: User already exists!');
console.error("A user with the same _id already exists.\n");
}
return res.render("auth/register", { message: req.flash('regMsg') || "" });
}else{
if(!req.user){
req.user=user; // Force the newly created user's way into the session in case it's not there by any means
console.log(req.user); // Make sure the user is stored in the session
}
passport.authenticate("local")(req,res,()=>{
res.redirect('/contactlist');
});
}
}
);
});
//#endregion
Every time I registered a new user, it was stored successfully in my MongoDB database. However, the callback leads to 400 Bad request consistently.
As is seen, I added a snippet to make sure the newly created user is stored in the session, and the console did told me it is there by returning:
{
_id: new ObjectId("6400f64b4542f09373a2b7ac"),
username: '[email protected]',
salt: '66fddb7390196bd0a1bf06455699fc74d4c3412e66b8b47ed272cb80bb1be218',
hash: '7f351f6f58c4299f3ba3d697e8b7efe80ef7596995b1615e09c80f3384cd34836a651bd7a4e1e9aec85e589c5f97f043a1e3fc87f74e7a2d03313529e36b4fc4cb0a1c923763830bc2866f69995c1f5ea4dc0e633a529d2e5e872815ea182956d8b99b1c9ed00012c82fefa75ebbf02da3abf565eda89d27d8fe204169021554786106eb67e3939fd51ba5b5810c192ee59488a78cbc119814e405715061571704366067b0c1810f16387cdd8de3dca0966ab89b4484dcd2ae839ac382520ea4b8ad1246e17d64e43e858de3a51986b150910ed9b482b49bd3807ef9ad89dd473df499ccd3464263c37dc5552c51d69084ecd3a19abe6039b308f694be93157e33f4b87168fd770e33e9f9fff8e9a0fbbbc8543b4e227a906a0a2e7cedcfad9305ff378f435afd60ce5095132b352a6165b7594bb14d0e3a957a050d1bb3bcac90fb9664154c95c014173949ab84f69545d89d2c178b40542f5841a22a1634b7fcd814d79e41e5a552351c4d8076c72362bedbaa9c524a3ecf01c9970efc98b3d909cf858d9dcd74632fa52533c273f9f7a4bec71769e9137e07c326b6d4a82298b70518070bada0befe4aeb053b72a79d99e54a768679b6256d4cfa5f2d508a6dfec208021240fbe8384db5f4e7ca8413b90cdc110e7b469df699b6035fe62f766999258d5c011c61e37ebcb37882b6b839215ae23058d54070b6505849963a',
__v: 0
}
As the user has been created as expected, I think there shouldn't be any issues for serialization/deserialization either. However, the next line on the console from morgan is:
POST /register 400 363.780 ms - -
In another effort, I changed the passport.authenticate logic like this:
passport.authenticate("local",{
successRedirect: "/contactlist",
failureRedirect: "/login",
failureFlash: true,
failureMessage: "User cannot be authenticated."
})(req,res,(err)=>{
if(err) console.error(err);
else res.redirect("/contactlist")
});
This prevented passport.authenticate() to return 400 Bad request; however, it always got redirected to the failureRedirect, which is "/login", and the if(err) console.error(err); in the callback never returned anything.
I've been stuck on this for a couple of days. Please help! Thank you in advance!
I think I found the problem, it is in the field useremail in
req.body.passport.authenticate()authenticates the user from the client-side request.To fix the issue, you should change the field name from
useremailtousernamewhen sending a POST request from the client side.