I am learning passport.js and session, and am trying to add a local login feature to my website.
What I was trying to do is as follows:
- Secret page: When users are authenticated, they can access to the secret page, otherwise they will be transfered to the login page.
- Login page: If the username and password match, users are authenticated and are transfered to the secret page, otherwise they would be transfered back to the login page.
- Register page: Users provide username and password, a new MongoDB document is created and stored in my database, meanwhile, the user is authenticated in this session and are transfered to the secret page.
My Problem:
- Login page works fine: The authentication process in the login page works perfectly fine. When logined, a cookie is sent to the browser, the user is authenticated in this session and is successfully accessed to the secret page.
- Register page data insert works fine: After register, the new password and username is successfully saved in the MongoDB database. User could login with this newly registered username.
- Register page authentication failed: The register page, although using the same passport.authenticate() function, failed in the authentication process. I didn't get any error messages on my console, either.
I searched on Google and tried several methods of passport authentication, and they all worked very well on the 'login' POST Request, but failed on the 'register' POST Request. I have read the documentation of passport-local and passport-local-mongoose. I have also tried this solution. But they all failed in the authentication process in the register page. I use express-session, passport, passport-local-mongoose packages.
I'm wondering if my understanding of passport authentication is still lacking? Thank you so much for your help and patience!
My Code:
EJS File - Register Page:
<!-- ... -->
<form action="/register" method="POST">
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" name="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-dark">Register</button>
</form>
<!-- ... -->
JS File:
require('dotenv').config();
const express = require('express');
const app = express();
const port = 3000;
const ejs = require('ejs');
const session = require('express-session');
const passport = require('passport');
const passportLocalMongoose = require('passport-local-mongoose')
app.use(express.urlencoded({
extended: true
}));
app.use(express.static("public"));
app.set("view engine", "ejs");
//session and passport set up
app.use(session({
secret: process.env.SECRET,
resave: false,
saveUninitialized: true,
cookie: {
sameSite: 'lax'
},
}))
app.use(passport.initialize());
app.use(passport.session());
//user database set up ////////
const mongoose = require("mongoose");
main().catch(err => console.log(err));
async function main() {
await mongoose.connect('mongodb://localhost:27017/userDB');
}
const userSchema = new mongoose.Schema({
username: {
type: String,
unique: true
},
password: String
})
userSchema.plugin(passportLocalMongoose)
const User = mongoose.model("User", userSchema)
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
//user database set up end ///////
//GET Request
app.get("/", function(req, res) {
res.render("home");
})
app.get("/login", function(req, res) {
res.render("login");
})
app.get("/register", function(req, res) {
res.render("register");
})
//Secret Page ////////////////////////////////
app.get("/secrets", function(req, res) {
if (req.isAuthenticated()) {
res.render("secrets")
} else(
res.redirect("/login")
)
})
app.get('/logout', function(req, res) {
req.logout(function(err) {
if (err) {
console.log(err);
}
res.redirect('/');
});
});
//POST request
//Register POST Request ////////////////////////////////
app.post("/register", function(req, res) {
User.register(new User({
username: req.body.username
}), req.body.password,
function(err, user) {
if (err) {
console.log(err);
res.redirect('/register')
}
passport.authenticate('local'), function(req, res) {
res.redirect("/secrets");
}
}
)
})
app.post('/login', passport.authenticate('local', {
failureRedirect: '/login',
}), function(req, res) {
res.redirect("/secrets");
});
app.listen(port, function() {
console.log("start listening to port 3000")
})