how to add passport js (local-strategy) in all routes - node.js

I added the passport authenticated to my login route but I do not know how to add it to the other routes. now (req.isAuthenticated) is true in the login route but It's false in all of the other routes!!! How can I add it to all routes so that when the user is logged in, 'req.authenticated' becomes true on them?
login.js:
const express = require("express");
const router = express.Router();
const path = require("path");
const passport = require("passport");
const session = require("express-session");
const flash = require("express-flash");
const methodOverride = require('method-override');
const bodyParser = require('body-parser');
const { getAdmins } = require("../queries/queries");
//middlewares
router.use(flash());
router.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
})
);
router.use(passport.initialize());
router.use(passport.session());
router.use(methodOverride('_method'));
//passport
const initializePassport = require("../passport-config");
initializePassport(
passport,
async (name) => {
let users = await getAdmins();
return users.find((user) => user.name == name)},
async (id) => {
let users = await getAdmins();
return users.find((user) => user.id == id)}
);
//get metod
router.get("/", checkAuthentication, (req, res) => {
res.render(path.join(__dirname, "../public/login.ejs"), {isLogin : req.isAuthenticated});
});
//post method
router.post(
"/",
passport.authenticate("local", {
successRedirect: "/messages",
failureRedirect: '/login',
failureFlash: true,
})
);
router.delete('/logout', (req, res)=>{
req.logOut();
res.redirect('/');
})
//check req authenticated
function checkAuthentication(req, res, next) {
if (req.isAuthenticated()) {
console.log('login:yes')
return next();
}
console.log('login:no');
return next();
}
module.exports = router;
passport-config.js:
const LocalStrategy = require("passport-local").Strategy;
function initialize(passport, getUserByName, getUserById) {
const authenticateUser = async (name, password, done) => {
const user = await getUserByName(name);
if (user == null) return done(null, false, { message: "sorry! user name is not exist" });
if(password == user.password){
return done(null, user);
} else done(null, false, {message : "incorrect password"});
};
passport.use(new LocalStrategy(authenticateUser));
passport.serializeUser((user, done)=> done(null, user.id));
passport.deserializeUser((id, done)=> done(null, getUserById(id)));
}
module.exports = initialize;

To solve this problem, I transferred this code from login.js to server.js:
//midlewares
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended : false}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

Related

Cannot GET /auth/google/callback | PassportJs

Why I'm getting this error! Cannot GET /auth/google/callback after choosing an account from the google login page I got redirected to a white page with the above error, its been a week working on this google login thing!
This is index.js file:
const mongoose = require("mongoose");
const authRoute = require("./routes/auth");
const cors = require("cors");
const app = express();
const cookieSession = require("cookie-session");
const passportSetup = require("./passport");
const passport = require ("passport");
app.use(cookieSession({name: "session", keys: ["mokhtarah"],
maxAge: 24 * 60 * 60 * 100 })
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
app.use(cors({origin: "http://localhost:3000",
methods: "GET,POST,PUT,DELETE",
credentials: true,}));
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use("/api/auth", authRoute);
app.use("/api/users", userRoute);
app.listen("4000", () => {
console.log("Backend is running.");
});
This is the passport.js file:
const User = require("./models/User");
const mongoose = require("mongoose");
const passport = require("passport");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
passport.use(
new GoogleStrategy(
{
clientID: "",
clientSecret: "",
callbackURL: "/auth/google/callback",
},
function (accessToken, refreshToken, profile, done) {
done(null, profile);
console.log(profile)
}
)
)
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
This is the auth.js file:
const router = require("express").Router();
const User = require("../models/User");
const passport = require("passport");
router.get("/google", passport.authenticate("google", { scope: ["profile"] }))
router.get(
"/google/callback",
passport.authenticate("google", {
successRedirect: 'http://localhost:3000/',
failureRedirect: 'http://localhost:4000/auth/google'
})
)
//LOGIN WITHOUT PASSPORTJS
router.post("/login", async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email });
// if(!user) return res.status(400).json("Wrong credentials!");
!user && res.status(400).json("Wrong credentials!");
const validated = await bcrypt.compare(req.body.password, user.password);
// if(!validated) return res.status(400).json("Wrong credentials!");
!validated && res.status(400).json("Wrong credentials!");
const { password, ...others } = user._doc;
return res.status(200).json(others);
} catch (err) {
return res.status(500).json(err);
}
});
Login without passportjs works fine no issues only the google login, I just want the profile data to appear on my console log!
The Google Cloud Console:
In the auth.js file add /auth as a prefix in /google/callback route and in the index.js file remove /api/auth.
auth.js
router.get('/auth/google/callback', // add **/auth**
(req,res,next)=>{
passport.authenticate('google', { failureRedirect: '/auth/google/error' }, async (error, user , info) => {
if (error){
return res.send({ message:error.message });
}
if (user){
try {
// your success code
return res.send({
data: result.data,
message:'Login Successful'
});
} catch (error) {
// error msg
return res.send({ message: error.message });
}
}
})(req,res,next);
});
index.js
const mongoose = require("mongoose");
const authRoute = require("./routes/auth");
const cors = require("cors");
const app = express();
const cookieSession = require("cookie-session");
const passportSetup = require("./passport");
const passport = require ("passport");
app.use(cookieSession({name: "session", keys: ["mokhtarah"],
maxAge: 24 * 60 * 60 * 100 })
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
app.use(cors({origin: "http://localhost:3000",
methods: "GET,POST,PUT,DELETE",
credentials: true,}));
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use("/", authRoute); // ====> change here
app.use("/api/users", userRoute);
app.listen("4000", () => {
console.log("Backend is running.");
});

Passport.js authentication goes in infinite loop

I have been trying to build the authentication using PassportJs and MongoDB. I am using PassportJS only to log in. But, while submitting the post request it does not redirect me to the failureRedirect route, nor to the SuccessRedirect one, instead, the web page enters into an endless loop.
The code I have written is -
It has 2 files- app.js and user.js
App.js file -
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const passport = require('passport');
const mongoose = require('mongoose');
require('./db/db')
var fileupload = require('express-fileupload');
const path = require('path');
const app = express();
app.use(fileupload({
useTempFiles: true
}));
const session = require('express-session');
const mongostore = require('connect-mongo');
app.use(express.static(path.join(__dirname,'public')));
// session middle ware
app.use(session({
secret : 'mysupersecret',
resave : false,
saveUninitialized : false,
store: mongostore.create({
mongoUrl: process.env.DB,
}),
cookie : { maxAge : 180 * 60 * 1000 }
}));
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static("public"));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(passport.session());
app.get("/", (req, res) => {
res.render("index");
});
app.use("/admin", require("./routes/admin"));
app.use("/user", require("./routes/user"));
app.use("/task", require("./routes/task"));
// PORT
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`Server started on port ${PORT}`));
User.js file -
const express = require("express");
const bodyParser = require("body-parser");
const router = express.Router();
const bcrypt = require("bcryptjs");
const passport = require("passport");
const User = require("../models/User");
const Task = require("../models/Task");
var LocalStrategy = require('passport-local');
// var bcrypt = require('bcryptjs');
var strategy = new LocalStrategy(function verify(email, password, done) {
try{
console.log(email);
User.findOne({email: email}, function (err, user) {
console.log(email);
if (err)
console.log(err);
if (!user) {
console.log("doen exist")
return done(null, false);
}
bcrypt.compare(password, user.password, function (err, isMatch) {
if (err)
console.log(err);
if (isMatch) {
return done(null, user);
} else {
console.log("galat password");
return done(null, false);
}
});
});
}catch(err){
console.log(err);
}
});
passport.use('epass',strategy);
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
// User login
router.get("/login", (req, res) => {
res.render("user-login");
});
router.post("/login", (req,res) => {
try{
passport.authenticate('epass', { failureRedirect: '/user/login' }),
function(req, res,next) {
res.redirect('/user');
}
}catch(err){
console.log(err);
}
});
router.get("/", (req, res) => {
res.render("user")
})
module.exports = router;
I have searched everywhere and tried all the available possible solutions but nothing is solving this.
passport.authenticate() should be used as a middleware, not as a regular function:
router.post("/login",
passport.authenticate('epass', { failureRedirect: '/user/login' }),
function(req, res,next) {
res.redirect('/user');
}
);
The way you were using it causes the request to POST /user/login to never finish, because it's not sending back any response.
EDIT: also, make sure that you either use the default field names of username and password for logging in, or add the relevant options to the constructor of LocalStrategy to tell it which fields it should be expecting.

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

Node.js auth page with passport-local and bcryptjs

I have a basic login auth page but whenever i try and login the page just reloads,
I'm relatively new to this and really need help.
server.js👇
const express = require("express");
const fs = require("fs");
const path = require("path");
const passport = require("passport");
const session = require("express-session");
const initializePasspost = require("./passport-config");
const flash = require("express-flash");
const bcrypt = require("bcryptjs");
initializePasspost(
passport,
email => users.find(user => user.email === email),
id => users.find(user => user.id === id)
);
let data = fs.readFileSync("./files/users.json");
let userData = JSON.parse(data);
app.set("view-engine", "ejs");
app.use(express.urlencoded({ extended: false }));
app.use("/assets", express.static(path.join(__dirname, "/assets")));
app.use("/script", express.static(path.join(__dirname, "/script")));
app.use(flash());
app.use(
session({
secret: "woff",
resave: false,
saveUninitialized: false
})
);
app.use(passport.initialize());
app.use(passport.session());
// Middleware
const checkAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
return next();
}
res.redirect("/admin");
};
const checkNotAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
return res.redirect("/");
}
next();
};
app.get("/test", checkAuthenticated, (req, res) => res.render("test.ejs"));
app.get("/register", checkNotAuthenticated, (req, res) =>
res.render("register.ejs")
);
app.post(
"/adminLogin",
passport.authenticate("local", {
successRedirect: "/test",
failureRedirect: "/adminLogin",
failureFlash: true
}),
(req, res) => {}
);
const PORT = process.env.PORT || 3000;
app.listen(PORT, err => {
console.log(`Server Running at port: ${PORT}`);
});
I know im not the best or optimal coder, but i need help.
passport-config.js👇
const bcrypt = require("bcryptjs");
const LocalStrategy = require("passport-local").Strategy;
const initialize = (passport, getUserByEmail, getUserById) => {
const authenticateUser = async (email, password, done) => {
const user = getUserByEmail(email);
if (user == null) {
return done(null, false, { message: "No user with that email" });
}
try {
if (bcrypt.compareSync(password, user.password)) {
return done(null, user);
} else {
return done(null, false, { message: "password Incorrect" });
}
} catch (e) {
return done(e);
}
};
passport.use(new LocalStrategy({ usernameField: "email" }, authenticateUser));
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => done(null, getUserById(id)));
};
module.exports = initialize;
I would have installed bcrypt but there was a problem installing it so I opted for bcryptjs.
I got some of the code from a youtube tutorial.
I don't know what to do. Please help. I'm stuck on this for more than a week.

My passport auth doesnt work on Heroku, user is not returned

My app and auth is working perfectly localy, however after deploying the server to heroku I am unable to login, because user object is not returned.
Here is my passport file:
const passport = require('passport');
const localStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const User = mongoose.model('users');
passport.serializeUser((user, done) => {
// console.log({user})
done(null, user._id)
})
passport.deserializeUser((id, done) =>
User.findById(id).then((user) => {
if (user) {
done(null, user)
} else {
}
})
);
passport.use(new localStrategy((username, password, done) => {
// console.log({username}, {password})
User.findOne({ username: username }, (err, user) => {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Username not found' });
}
if (!user.comparePassword(password, user.password)) {
return done(null, false, { message: 'Incorrect password.' });
}
// console.log('user', user)
return done(null, user);
});
}));
Routes:
const passport = require('passport');
const mongoose = require('mongoose');
const User = mongoose.model('users');
module.exports = (app) => {
app.post('/login',
passport.authenticate('local', {
successRedirect: '/loginSuccess',
failureRedirect: '/loginFailed',
})
);
app.get('/loginSuccess', (req, res) => {
res.send({ success: true, test:'test', user: req.user })
})
app.get('/loginFailed', (req, res) => {
res.send({ success: false, error: "Incorrect credentials" })
})
};
And I dont know if its helpful, but my index file:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const cookieSession = require('cookie-session');
const keys = require('./config/keys');
require('./models/user');
require('./services/passport');
mongoose.connect(keys.mongoUri, { useNewUrlParser: true })
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(
cookieSession({
maxAge: 30 * 24 + 60 * 60 * 1000, //30 days
keys: [keys.cookieKey]
})
);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
next();
});
app.use(passport.initialize());
app.use(passport.session());
//ROUTES
require('./routes/auth')(app);
require('./routes/game')(app);
const PORT = process.env.PORT || 5000;
app.listen(PORT);
After login is successfull I send back object containing 3 other objects, success bool value, user object with user info and for the sake of testing, test object containing a string.
Everything is returned, except for user object. What could be the issue?

Resources