Setting up passport for the first time. isAuthenticated() always returning false - node.js

I'm working through a learning module on authentication and security and I'm trying to get passport up and running but I seem to be having trouble. The code included below all works as you'd expect, except that when users are redirected from the /register post route to the /secrets route, they are not authenticated, in spite of .register() having worked (otherwise the logic in the route would have redirected me back to the /register get route instead of the login page via the secrets route).
require("dotenv").config();
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const ejs = require("ejs");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static("public"));
app.set("view engine", "ejs");
app.use(
session({
secret: "Our little secret.",
resave: false,
saveUninitialized: false
})
);
app.use(passport.initialize());
app.use(passport.session());
mongoose.connect("mongodb://localhost:27017/userDB", { useNewUrlParser: true });
mongoose.set("useCreateIndex", true);
const userSchema = new mongoose.Schema({
username: String,
password: String
});
userSchema.plugin(passportLocalMongoose);
const Users = new mongoose.model("Users", userSchema);
passport.serializeUser(Users.serializeUser());
passport.deserializeUser(Users.deserializeUser());
app.listen(3000, (req, res) => {
console.log("Listening on port 3000.");
});
app.get("/", (req, res) => {
res.render("home");
});
app.get("/login", (req, res) => {
res.render("login");
});
app.get("/register", (req, res) => {
res.render("register");
});
app.get("/secrets", (req, res) => {
console.log(req.isAuthenticated())
if (req.isAuthenticated()) {
res.render("secrets");
} else {
res.redirect("/login");
}
});
app.post("/register", (req, res) => {
console.log(req.body.username)
console.log(req.body.password)
Users.register(
{ username: req.body.username },
req.body.password,
(error, user) => {
if (error) {
console.log('there was an error: ', error);
res.redirect("/register");
} else {
passport.authenticate("local")(req, res, () => { //////////////not authenticating
res.redirect("/secrets");
});
}
}
);
});
app.post("/login", (req, res) => {});
any help figuring out why isAuthenticaed() is returning false would be greatly appreciated. thank you :)

You have to define your local strategy :
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
here it has queried User information from the database ( Mongodb for instance) in case of successful response it will pass.

Related

req.isAuthenticated() always returns false

I am new to the Passport.js. Whenever I login or register through the routes, req.isAuthenticated() always returns false and the secrets view is never rendered. Here is my app.js:
`
require("dotenv").config();
const express = require("express");
const bodyParser = require("body-parser");
const session = require("express-session");
const passport = require("passport");
const LocalStrategy = require("passport-local")
const passportLocalMongoose = require("passport-local-mongoose");
const mongoose = require("mongoose");
mongoose.set("strictQuery", true);
uri = "mongodb://localhost:27017/usersDB";
const userSchema = new mongoose.Schema({
username: String,
password: String
});
userSchema.plugin(passportLocalMongoose);
const User = new mongoose.model("User", userSchema);
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
app.set("view engine", "ejs");
app.use(session({
secret: "MyLittleSecret",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.get("/", function(req, res) {
res.render("home");
});
app.get("/secrets", function(req, res) {
if(req.isAuthenticated) {
res.render("secrets");
} else {
res.redirect("/login");
}
});
app.route("/register")
.get(function(req, res) {
res.render("register");
})
.post(async function(req, res) {
await User.register({username: req.body.username}, req.body.password, function(err, user) {
console.log("In the User.register callback function");
if(err) {
console.log(err);
res.redirect("/register");
} else {
passport.authenticate("local")(req, res, function() {
res.redirect("/secrets");
});
}
});
});
app.route("/login")
.get(function(req, res) {
res.render("login",{
errorMessage: ""
});
})
.post(async function(req, res) {
const userInstance = new User({
username: req.body.username,
password: req.body.password
});
req.login(userInstance, function(err) {
if(err) {
console.log(err);
} else {
passport.authenticate("local")(req,res,function() {
res.redirect("/secrets");
});
}
});
});
app.listen(3000, function() {
console.log("Server started listening to port 3000");
});
I searched on the web and tried the various orders of middleware. I could not solve the problem.

passport js to authenticate user login not working Local Strategy not being called

Can someone explain to me the reason why LocalStrategy is not being called when I'm trying to login?
Basically nothing happens when I login it just refreshes the page.
require("dotenv").config()
const ejs = require("ejs");
const express = require("express")
const session = require('express-session');
const mongoose = require('mongoose')
const passport = require("passport")
const LocalStrategy = require('passport-local').Strategy
const bcrypt = require("bcrypt")
const flash = require("express-flash")
//const User = require("./users")
//creating application
const app = express()
//const initializePassport = require("./passportconfig")
//connection to MongoDB with mongoose
main().catch(err => console.log(err));
async function main() { await mongoose.connect('mongodb://localhost:27017/passportDB') }
const userSchema = new mongoose.Schema({
name: String,
password: String,
userEmail: String
})
const User = mongoose.model("User", userSchema);
//middleware
//connecting to ejs
app.set("view engine", "ejs")
//connecting error text giver
app.use(flash())
//setup session
app.use(session({
secret: String(process.env.SECRET),
resave: false,
saveUninitialized: false,
cookie: { maxAge: 1000 * 60 * 60 * 24 * 7 }
}))
//connecting to body-parser
app.use(express.urlencoded({ extended: false }))
//passport.js
app.use(passport.initialize())
app.use(passport.session())
//serialize and deserialize session
passport.serializeUser(function (user, done) {
console.log('Deserialize user called.');
// #ts-ignore
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
console.log('Deserialize user called.');
User.findById(id, function (err, user) {
done(err, user);
});
});
//initializePassport(passport)
passport.use(new LocalStrategy((email, password, done) => {
User.findOne({ userEmail: email }, async function (err, user) {
if (err) {return done(err)}
if (!user) { return done(null, false, { message: 'No user with that email' }) }
if (await bcrypt.compare(password, user.password) == false) { return done(null, false, { message: 'No user with that email' }) }
return done(null, user);
});
}))
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect("/login");
}
app.get("/", isLoggedIn, (req, res) => {
res.render('index.ejs', { name: "Kyle" })
})
app.get("/login", (req, res) => {
res.render('login.ejs')
})
app.get("/register", (req, res) => {
res.render('register.ejs')
})
app.post("/register", async (req, res) => {
//10 is the value to generate the salt higher = more salted
try {
const hashedPassword = await bcrypt.hash(req.body.password, 10)
const user = new User({
name: req.body.name,
password: hashedPassword,
email: req.body.email
})
await user.save()
console.log(user)
res.redirect('login')
} catch {
res.redirect('register')
}
})
app.post("/login", passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash: true
}))
app.listen(3000, ()=> {
console.log("listening on port 3000")
})
Is there something I am missing?
The app.post for register is working all the data is entering the database it's simply for the login that's not working and it's because passport.authenticate is not working for the login post

Bad Request in Node Js using passport Js

I am trying to build a registration and login page using passport-local-mongoose.
When I click on submit signup button I get an error which says bad request.
I am getting "Bad Request" while registering, but the details are being stored in MongoDB. Not sure where I am making a mistake.
Please help me out.
Here is my register POST API.
let express = require('express');
let mongoose = require('mongoose');
const passport = require('passport');
const LocalStrategy = require('passport-local');
const passportLocalMongoose = require('passport-local-mongoose');
var expressValidator = require('express-validator');
const bodyParser = require('body-parser')
const { check, validationResult } = require('express-validator');
const Admin = require('../models/admin-model');
let router = express.Router();
const app = express();
//Creating a Secret Key to Hash Password
router.use(require('cookie-session')({
secret: 'jdkjhLGUL#^&%^%(*)&^%#!gkjh', // Encode/Decore Session
resave: false,
saveUninitialized: false
}));
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
}, Admin.authenticate()));
//Encrypting and Decrypting the Password for Security
passport.serializeUser(Admin.serializeUser()); //session Encoding
passport.deserializeUser(Admin.deserializeUser());
// passport.use(new LocalStrategy(Admin.authenticate()));
//Setting the View Engine to take EJS Pages
app.set('view engine', "ejs");
app.set('views', "./views")
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/public'));
mongoose.connect("mongodb://localhost:27017/node-auth-db", { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('Connected to node-auth-db successfully....!'))
.catch(err => console.log(err))
router.get('/', (req, res) => {
res.render('home');
});
router.get('/login', (req, res) => {
res.render('signin');
});
router.post('/login', passport.authenticate("local", {
successRedirect: '/admin/addnews',
failureRedirect: '/login'
}));
//Registration
router.get('/register', (req, res) => {
res.render('signup');
});
router.post('/register', (req, res) => {
Admin.findOne({ username: req.body.email }, (err, result) => {
if (err) throw err;
if (!result) {
Admin.register(new Admin({ name: req.body.name, username: req.body.email }),
req.body.password, function (err, admin) {
if (err) throw err;
passport.authenticate("local")(req, res, function () {
res.redirect('/admin/login');
})
}
)
}
else {
res.redirect('/admin/register');
}
});
});
//Add News
router.get('/addnews', isLoggedIn, (req, res) => {
res.render('addnews');
});
router.post('/addnews', (req, res) => {
News.create(req.body, (err, data) => {
if (err) throw err;
const htmlMsg = encodeURIComponent('Added News DONE !');
res.redirect('/admin/addnews');
})
});
//Creating a Authentication Token to secure the logging and Logout.
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/admin/login');
}
router.get('/logout', (req, res) => {
req.logOut();
res.redirect('/admin');
});
module.exports = router;[]
Might be the issue is here you are passing req.body.password outside admin module
Admin.register(new Admin({ name: req.body.name, username: req.body.email, req.body.password}), function (err, admin) {
if (err) throw err;
passport.authenticate("local")(req, res, function () {
res.redirect('/admin/login');
})
}
)

successRedirect is not working in passport login passport-local

I am using node.js express with sequelize and database postgreSql.the problem is in passport login failureRedirect works properly sucessRedirect does not redirect to the page that I want. It still loading and not responding anything and does not come any error.
when I submit login it will check for errors if errors it will work perfectly in failureRedirect but in Success it does not work like page has loading only not goes to the destination page and if I stop the project and restart the project it will be in destination page!! i dont know what is the problem help me.
mainController.js
const express = require("express");
const sessions = require("express-session");
require("../model/MasterUser.model");
const passport = require("passport");
var session = sessions;
const router = express.Router();
router.get("/dashboard", (req, res) => {
res.render('dashboard');
});
router.get("/login", (req, res) => {
res.render("login", { layout: "login.hbs" });
});
router.post(
"/login",
passport.authenticate("local", {
successRedirect: "/main/dashboard",
failureRedirect: "/main/login",
failureFlash: true,
})
);
module.exports = router;
passport.js
const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcryptjs");
const sequelize = require("sequelize");
const masterUser = require("../model/MasterUser.model");
module.exports = function (passport) {
passport.use(
new LocalStrategy(
{ usernameField: "user_name" },
(user_name, password, done) => {
// Match user
masterUser.findOne({ where: { user_name: user_name } }).then((user) => {
if (!user) {
return done(null, false, {
message: "This username is not registered",
});
}
// Match password
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: "Password incorrect" });
}
});
});
}
)
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
masterUser.findByPk(id, (err, user) => {
done(err, user);
});
});
};
index.js
const express = require("express");
const Handlebars = require("handlebars");
var flash = require("connect-flash");
const app = express();
const path = require("path");
const bodyparser = require("body-parser");
const expressHandlebars = require("express-handlebars");
const passport = require("passport");
const sessions = require("express-session");
var session = sessions;
const MainController = require("./controllers/MainController");
const db = require("./config/database");
//test db
db.authenticate()
.then(() => console.log("Database Connected..."))
.catch((err) => console.log("error" + err));
//for security purpose
const cors = require("cors");
app.use(
cors()
);
//Passport Config
require("./config/passport")(passport);
app.use(cookieParser());
//use body parser
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({ extended: true }));
const {
allowInsecurePrototypeAccess,
} = require("#handlebars/allow-prototype-access");
app.use(
bodyparser.urlencoded({
urlencoded: true,
})
);
app.use(
sessions({
secret: "secret_key",
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60000 },
})
);
// use flash for show messages
app.use(flash());
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
//flash messages
app.use((req, res, next) => {
res.locals.success_msg = req.flash("success_msg");
res.locals.error_msg = req.flash("error_msg");
res.locals.error = req.flash("error");
next();
});
//setting up view Engine
app.set("views", path.join(__dirname, "/views"));
//using the hbs
app.engine(
"hbs",
expressHandlebars({
extname: "hbs",
defaultLayout: "default",
layoutsDir: __dirname + "/views/layouts",
handlebars: allowInsecurePrototypeAccess(Handlebars),
})
);
app.set("view engine", "hbs");
//route for Main
app.use("/main", MainController);
//default
app.get("/", (req, res) => {
res.render("login");
});
app.listen(3000, () => {
console.log("App listening on port 3000!");
});
the problem has been solved guys I made done wrong code in deserializeUser.
passport.js before
passport.deserializeUser((id, done) => {
masterUser.findByPk(id, (err, user) => {
done(err, user);
});
});
};
passport.js after
passport.deserializeUser(function (id, done) {
masterUser.findOne({ where: { id: id } }).then((user) => {
done(null, user);
});
});
the problem is for sequelize get the user data is different so now its worked for me.this is useful for who using express with sequelize and passport with postgresql

req.user undefined using Express & Node & Passport

I am currently creating a small user authentication app using Node + Express + Passport. When the user logs in, they are rerouted automatically to the index page "/" and a session should be established with passports authentication. For some reason when trying to console.log(req.user), it is returning "undefined".
The authentication with passport seems to be working properly with the post route
app.post("/login", passport.authenticate("local", {
successRedirect: "/home",
failureRedirect: "/login"
}), (req, res) => {
})
But the session is not being established with the user model. I'd like to eventually store the userId in the session. Here is a look at my current set up with user model and passport implementation on the server file.
const mongoose = require("mongoose");
const passportLocalMongoose = require('passport-local-mongoose');
const userSchema = mongoose.Schema({
username: String,
email: String,
password: String
});
userSchema.plugin(passportLocalMongoose);
const user = mongoose.model("User", userSchema);
module.exports = user;
-----------------------------------------------------------------------------------------
const express = require("express"),
mongoose = require("mongoose"),
bodyParser = require("body-parser"),
session = require("express-session"),
User = require("./models/user"),
passport = require('passport'),
LocalStragety = require('passport-local'),
app = express();
mongoose.connect("mongodb://localhost/shopping_cart_app", { useNewUrlParser: true })
.then(console.log("MongoDB Connected"))
.catch(err => console.log(err));
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + '/views'));
app.use(session({
secret: "secret",
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStragety(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.post("/login", passport.authenticate("local", {
successRedirect: "/home",
failureRedirect: "/login"
}), (req, res) => {
})
I've tried looking into Passports config a bit more but on the documentation provided, it states that once passport.authenticate runs, a session with the user is established. Any tips would be greatly appreciate.
Thanks
I know this may seem simple, but have you tried req.body.user?
The req.body contains the data submitted by the user. The documentation suggest that you use a body parser to populate the information because it's undefined by default. However, instead of using the app object I use express router without parsing.
const express = require("express");
const router = express.Router();
router.post("/login", passport.authenticate("local", {
successRedirect: "/home",
failureRedirect: "/login"
}), (req, res) => {
console.log(req.body.user);
})
for more information: req.body
Try this one, In my project, it is working.
LocalStrategy
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
var mongoose = require('mongoose');
var admins = mongoose.model('admins');
var bCrypt = require('bcrypt-nodejs');
var flash = require('connect-flash');
var moment = require('moment');
// User
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(obj, done) {
console.log("deserializing " + obj);
done(null, obj);
});
passport.use('adminlogin',new LocalStrategy(
function(username, password, done) {
admins.findOne({ 'email' : username },
function(err, user) {
//console.log(username);
if (err)
return done(err);
if (!user){
//console.log('Username '+username+' does not Exist. Pleasr try again.');
return done(null, false, { message: 'Incorrect Username/Password. Please try again.' });
}
if (!isValidPasswordAdmin(user, password)){
//console.log('Invalid Password');
return done(null, false, { message: 'Incorrect Password. Please try again.' });
}
return done(null, user);
}
);
})
);
var isValidPassword = function(user, app_pin){
return bCrypt.compareSync(app_pin, user.app_pin);
}
var isValidPasswordAdmin = function(user, password){
return bCrypt.compareSync(password, user.password);
}
module.exports = passport;
Login Route
router.post('/login', function (req, res, next) {
admins.find({}, function (err, user) {
if (err) {
console.log('internal database error');
req.flash('error', 'Database Error');
res.redirect('/admins');
} else {
passport.authenticate('adminlogin', function (err, user, info) {
if (err) {
console.log(err);
req.flash('error', 'Database Error');
res.redirect('/admins');
} else if (!user) {
req.flash('error', info.message);
res.redirect('/admins');
} else {
req.logIn(user, function (err) {
if (err) {
req.flash('error', 'Database Error');
res.redirect('/admins');
} else {
res.redirect('/admins/home');
}
});
}
})(req, res, next);
}
});
});

Resources