Passport session doesn't retain after post - javascript

I'm new to Node.js app, and I writing authentication by passport. I can login and authentication routine works fine. However, after post, isAuthenticated() return false and redirect to index page. It seems like the user session is gone after doing post.
Could anybody tell me how to fix it? Here's my code.
app.js
var createError = require('http-errors');
var express = require('express');
const expressLayouts = require('express-ejs-layouts');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
var flash = require('connect-flash');
const session = require('express-session')
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy
var manageRouter = require('./routes/manage');
var app = express();
app.use(fileUpload());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('tiny'));
app.use(expressLayouts);
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static('public'));
app.use(flash());
app.use(cookieParser('remote_teach'));
app.use(bodyParser.json());
app.use(session({
secret: "remote_teach",
resave: true,
saveUninitialized: true,
cookie: {maxAge: 60 * 60 * 24 * 1000}
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next){
if (req.user && req.isAuthenticated()) {
res.locals["login"] = true;
}
return next();
});
app.use('/manage', manageRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
console.log("404");
next(createError(404));
});
module.exports = app;
route/manage.js
var express = require('express');
var router = express.Router();
var file_system = require('file-system');
var fs = require('fs');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
var md5 = require('md5');
const { encrypt, decrypt, randomString } = require('../crypto');
const db_configure = require('../configure');
var rootDirectory = 'public/data/';
// 資料庫
var mysql = require('mysql');
var connection = mysql.createConnection({
host : db_configure.db_host,
port : db_configure.db_port,
user : db_configure.db_user,
password : db_configure.db_pwd,
database : db_configure.db_name
});
// 顯示登入頁面
router.get('/login', function(req, res, next){
if (req.isAuthenticated()) {
res.redirect('/manage/index');
}else{
res.render('manage/login');
}
});
// Passport JS 登入驗證
passport.use(new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
// Verify Callback
function(req, email, passwd, done) {
//verrify if the user is existed
})
);
passport.serializeUser(function(user, done) {
done(null, user.user_id)
});
passport.deserializeUser(function(id, done) {
//select user and deserialize
done(null, user);
});
router.post('/login', passport.authenticate('local', { successRedirect: '/manage',
failureRedirect: '/',
failureFlash: true})
);
router.post('/user/create', isAuthenticated, function(req, res, next){
var name = req.body.name;
var email = req.body.email;
var password = md5(req.body.password);
connection.query('INSERT INTO users (name, email, password) VALUES (?, ?, ?)',[name, email, password], function (error, results, fields){
if (error){
console.log(error);
}
res.redirect('/manage/users');
});
});
function isAuthenticated(req, res, next) {
if (req.user && req.isAuthenticated()) {
return next();
}
return res.redirect('/');
}
module.exports = router;

Related

Router.use() requires a middleware function but got undefined

I want make auth app using nodejs and got error like the title :(
but code for app.js is already like this
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var session = require('express-session')
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({
secret: '123456cat',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60000 }
}))
app.use(express.static(path.join(__dirname, 'public')));
var registrationRouter = require('./routes/registration-route').default;
var loginRouter = require('./routes/login-route').default;
var dashboardRouter = require('./routes/dashboard-route').default;
var logoutRouter = require('./routes/logout-route');
app.use('/', registrationRouter);
app.use('/', loginRouter);
app.use('/', dashboardRouter);
app.use('/', logoutRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
app.listen(3000);
module.exports = app;
this is registration-route.js
var express = require('express');
var router = express.Router();
var db = require('../database');
// to display registration form
router.get('/register', function(req, res, next) {
res.render('registration-form');
});
// to store user input detail on post request
router.post('/register', function(req, res, next) {
inputData ={
username: req.body.username,
email_address: req.body.email_address,
password: req.body.password,
confirm_password: req.body.confirm_password
}
// check unique email address
var sql='SELECT * FROM registration WHERE email_address =?';
db.query(sql, [inputData.email_address] ,function (err, data, fields) {
if(err) throw err
if(data.length>1){
var msg = inputData.email_address+ "was already exist";
}else if(inputData.confirm_password != inputData.password){
var msg ="Password & Confirm Password is not Matched";
}else{
// save users data into database
var sql = 'INSERT INTO registration SET ?';
query(sql, inputData, function (err, data) {
if (err) throw err;
});
var msg ="Your are successfully registered";
}
res.render('registration-form',{alertMsg:msg});
})
});
module.exports = router;
login-route.js
var express = require('express');
var router = express.Router();
var db = require('../database');
/* GET users listing. */
router.get('/login', function(req, res, next) {
res.render('login-form');
});
router.post('/login', function(req, res){
var email = req.body.email;
var password = req.body.password;
var sql='SELECT * FROM registration WHERE email_address =? AND password =?';
db.query(sql, [email, password], function (err, data, fields) {
if(err) throw err
if(data.length>0){
req.session.loggedinUser= true;
req.session.email= email;
res.redirect('/dashboard');
}else{
res.render('login-form',{alertMsg:"Your Email Address or password is wrong"});
}
})
})
module.exports = router;
logout-route.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/logout', function(req, res) {
req.session.destroy();
res.redirect('/login');
});
module.exports = router;
dashboard-route.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/dashboard', function(req, res, next) {
if(req.session.loggedinUser){
res.render('dashboard',{email:req.session.emailAddress})
}else{
res.redirect('/login');
}
});
module.exports = router;
I already see questions like this but none of the answers are working for my case problem
also I'd tried to npm clear cache --force but nothing changed
also had been uninstalled and reinstalled for node_modules , package-lock but always got same error
Change all of these:
var registrationRouter = require('./routes/registration-route').default;
to remove the .default so you just have this:
const registrationRouter = require('./routes/registration-route');
.default is something that is used with ESM modules, not with CommonJS modules.
Also, you shouldn't be using var any more. It's obsolute now. Use const for these.

Node.js passport local authentication is not calling the middleware

I´m trying to use local authentication with passport. According to the passport doc everything seems easy, but for some reason when I call the passport.authenticate the middleware is not running. Just nothing happens.
When I submit the signup form, the post signup function is called.I got the "Received" in my browser, however, I cannot see any console.log that I have in the passport.use callback.
Server:
const express = require('express');
const morgan = require('morgan');
const expressHandleBars = require('express-handlebars');
const path = require('path');
const flash = require('connect-flash');
const session = require('express-session');
const mysqlStore = require('express-mysql-session');
const passport = require('passport');
const { database } = require('./keys');
// Initializations
const app = express();
require('./lib/passport');
// Setting
app.set('port', process.env.PORT || 4000);
app.set('views', path.join(__dirname, 'views'));
app.engine('.hbs', expressHandleBars({
defaultLayout: 'main',
layoutsDir: path.join(app.get('views'), 'layouts'),
partialsDir: path.join(app.get('views'), 'partials'),
extname: '.hbs',
helpers: require('./lib/handlebars')
}));
app.set('view engine', '.hbs')
// Middleware
app.use(session({
secret: 'whatever',
resave: false,
saveUninitialized: false,
store: new mysqlStore(database)
}));
app.use(morgan('dev'));
app.use(express.urlencoded({extended: false}));
app.use(express.json());
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
// Global variables
app.use((req, res, next) => {
app.locals.success = req.flash('success');
next();
});
// Routes
app.use(require('./routes'));
app.use(require('./routes/authentication'));
app.use('/links', require('./routes/links'));
// Public
app.use(express.static(path.join('__dirname', 'public')));
// Starting the server
app.listen(app.get('port'), () => {
console.log('Server on port', app.get('port'));
});
Passport config file (lib/passport.js):
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const pool = require('../database');
const helpers = require('./helpers');
passport.use('local-signup', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
}, async function(req, username, password, done) {
console.log("Authenticated!!");
console.log(req.body);
}
));
Router calling authenticate (routes/authenticate.js):
const express = require('express');
const passport = require('passport');
const router = express.Router();
router.get('/signup', (req, res) => {
res.render('auth/signup');
});
router.post('/signup', (req, res) => {
passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signupFailure',
failureFlash: true
}, (req, res) => {
res.send("Authenticating");
});
//console.log(req.body);
res.send('Received');
});
router.get('/profile', (req, res) => {
res.send('This is your profile');
});
module.exports = router;
Passport.authenticate() returns a middleware function, you're not calling it.
passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signupFailure',
failureFlash: true
}, (req, res) => {
res.send("Authenticating");
})(req, res)

Cannot GET /users/test nodejs

I'm trying to load /users/(username) for specific user profile pages, however I'm getting a Cannot GET /users/test error. I had it working at one point but then I added a function and it's broken again (I'm thinking the problem may be there in the route). Here's the relevant files. Any help would be greatly appreciated. Thank you!
app.js:
const fs = require('fs');
const _ = require('lodash');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const expressValidator = require('express-validator');
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const mongo = require('mongodb');
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/tipcup');
var db = mongoose.connection;
const routes = require('./routes/index');
const users = require('./routes/users');
const user = require('./routes/user');
// Init App
var app = express();
// View Engine
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({defaultLayout: 'layout'}));
app.set('view engine', 'handlebars');
// BodyParser middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use(cookieParser());
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
// Express Session
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
// Passport Init
app.use(passport.initialize());
app.use(passport.session());
// Express Validator
app.use(expressValidator ({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length){
formParam += '[' + namespace.shift() + ']';
}
return {
param: formParam,
msg: msg,
value: value
};
}
}));
// Connect Flash
app.use(flash());
// Global Vars
app.use(function (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');
res.locals.user = req.user || null;
next();
});
app.use('/', routes);
app.use('/users', users);
app.use('/user/:username', user);
// Set Port
app.set('port', (process.env.PORT || 3000));
app.listen(app.get('port'), function(){
console.log('Server started on port '+app.get('port'));
});
user.js route:
var express = require('express');
var router = express.Router();
var User = require('../models/user');
// GET user by username
router.get('/:username', function(req, res) {
//var username = req.params.username;
User.getUserByUsername(function(err, user) {
if(err) {
res.send('error');
next();
}
const vm = user;
res.render('user', vm);
});
//res.render('user');
});
module.exports = router;
Its looks like you are defining the User Id twice
In app.js you are mounting the users routes /user/:username with the line
app.use('/user/:username', user);
Then in user.js you are declaring the get to /:username with the line
router.get('/:username', function(req, res) {
I would think this would produce a route with the signature /user/:username/:username
I would suggest remove the /:username one of the files
router.get('/:username', function(req, res) {
var username = req.params.username;
User.getUserByUsername(username).then(function(err, user){
res.json(user);
});
for mongoose you can do this:
router.get('/:username', function(req, res) {
var username = req.params.username;
User.getUserByUsername(username,function(err, user){
res.json(user);
});
});

Route separation in express routing with passing passport instance

I'm trying to add user-login module to an existing app in node. It is using separate route files for each module and one main route file to use all the child routes which is ultimately used in server.js
When I try to pass passport instance to the user route, it gives me error as passport is not defined. Here is my app code and structure:
app
views
user
index.ejs
login.ejs
signup.ejs
profile.ejs
routes
docs
index.js
user
index.js
index.js
config
passport.js
server.js
server.js
const express = require('express')
const app = express()
const path = require('path')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const passport = require('passport')
const flash = require('connect-flash')
const session = require('express-session')
const routes = require('./routes/')
const port = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, 'public')));
require('./config/passport')(passport);
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(session({ secret: '********' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use('/', routes)(app,passport);
const server = app.listen(port, function(){
console.log('Server listening on port '+port);
});
config/passport.js
var LocalStrategy = require('passport-local').Strategy;
const sql = require('mssql')
const bcrypt = require('bcrypt-nodejs')
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function (username, done) {
done(null,username);
});
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
process.nextTick(function() {
var strSQL = "SELECT count(id) as uCount FROM <tbl> WHERE username = '"+email+"'";
var cb1 = function(err,recordset){
if(recordset[0].uCount>0){
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else{
var strSQL1 = "INSERT INTO <tbl>(username, password) VALUES('"+email+"','"+generateHash(password)+"')";
var cb2 = function(err,recordset){
return done(null, recordset,req.flash('signupMessage', 'Email registered successfully.'));
};
executeQuery(strSQL1,'INSERTION','<tbl>',cb2);
}
};
executeSelection(strSQL,'SELECTION','<tbl>',cb1);
});
}));
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
var strSQL = "SELECT a.count, id, username, password FROM <tbl> c , (SELECT COUNT(dbid) count FROM <tbl> b WHERE b.username = '"+email+"' ) a WHERE c.username = '"+email+"'";
var cb1 = function(err,recordset){
if(recordset[0].uCount <= 0){
return done(null, false, req.flash('loginMessage', 'No user found.'));
}
if (!validPassword(password,recordset[0].password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, recordset[0]);
};
executeSelection(strSQL,'SELECTION','<tbl>',cb1);
}));
};
executeSelection = function(strSQL, operationType, tableName, cb){
var request = new sql.Request(connection);
request.query(strSQL,function(err,recordset) {
if(err){
logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
}
logger.info(operationType+' ON '+tableName+' successful!');
cb(err,recordset);
});
};
executeQuery = function(strSQL, operationType, tableName, cb,validateClient) {
var request = new sql.Request(connection);
request.query(strSQL,function(err, recordset) {
if(err){
logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
}
logger.info(operationType+' ON '+tableName+' successful!');
if(cb){
cb(validateClient);
}
});
};
generatePasswordHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
validatePassword = function(curPass, dbPass) {
return bcrypt.compareSync(curPass, dbPass);
};
routes/index.js
const mainroute = require('express').Router()
/* ---- other existing routes included ---- */
const r_docs = require('./docs')
const r_user = require('./user') /*my custom route*/
/* ---- all other routes ---- */
mainroute.use('/docs', r_docs);
mainroute.use('/user', r_user)(app, passport); /*my custom route*/
mainroute.get('/', function(req, res){
res.render('home');
});
module.exports = function(app, passport){
mainroute;
}
routes/user/index.js
const express = require('express')
const router = express.Router()
router.get('/', function(req, res) {
res.render('user/index.ejs');
});
router.get('/login', function(req, res) {
res.render('user/login.ejs', { message: req.flash('loginMessage') });
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile',
failureRedirect : '/login',
failureFlash : true
}));
router.get('/signup', function(req, res) {
res.render('user/signup.ejs', { message: req.flash('signupMessage') });
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile',
failureRedirect : '/signup',
failureFlash : true
}));
router.get('/profile', isLoggedIn, function(req, res) {
res.render('user/profile.ejs', {
user : req.user
});
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
module.exports = function(app, passport) {
router;
}
Please suggest what am I doing wrong here. Thanks
You should wrap your main and user routes to run their logic when you call them and at end return prepared route:
routes/index.js
module.exports = function(app, passport) {
const mainroute = require('express').Router()
/* ---- other existing routes included ---- */
const r_docs = require('./docs');
const r_user = require('./user'); /*my custom route*/
/* ---- all other routes ---- */
mainroute.use('/docs', r_docs);
mainroute.use('/user', r_user)(app, passport); /*my custom route*/
mainroute.get('/', function(req, res) {
res.render('home');
});
return mainroute;
};
routes/user/index.js
module.exports = function(app, passport) {
const express = require('express');
const router = express.Router();
router.get('/', function(req, res) {
res.render('user/index.ejs');
});
router.get('/login', function(req, res) {
res.render('user/login.ejs', {
message: req.flash('loginMessage')
});
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true
}));
router.get('/signup', function(req, res) {
res.render('user/signup.ejs', {
message: req.flash('signupMessage')
});
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signup',
failureFlash: true
}));
router.get('/profile', isLoggedIn, function(req, res) {
res.render('user/profile.ejs', {
user: req.user
});
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
return router;
};
You need to require it at the top of your user/index.js. Simply:
var passport = require('passport');
Then to make sure the user is authenticated:
router.get('/some/path', isLoggedIn, function(req, res) {
var user = req.user;
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}

node.js login with passport

I am implementing a basic login system with passport but I keep receiving this error when I login with the correct credentials:
Express
500 TypeError: Cannot read property 'passport' of undefined
However works fine when I login with wrong credentials by redirecting back to login page. Help?
app.js
//dependencies
var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var mongoose = require('mongoose');
var passport = require('./auth');
var app = express();
server = require('http').createServer(app),
io = require('socket.io').listen(server);
// all environments
app.use(passport.initialize());
app.use(passport.session());
....
app.use(app.router);
app.use(require('less-middleware')({src: path.join(__dirname, 'public')}));
app.use(express.static(path.join(__dirname, 'public')));
......
//routes
app.get('/login', routes.login);
app.post('/login', passport.authenticate('local', {
failureRedirect: '/login',
successRedirect: '/user'
}));
app.get('/user', routes.user);
index.js
exports.login = function(req, res) {
res.render('login', {title: 'Log in'});
};
exports.user = function(req, res) {
if (req.session.passport.user === undefined) {
res.redirect('/login');
} else {
res.render('user', {title: 'Welcome!',
user: req.user
})
}
};
auth.js
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
if (username === 'admin' && password === 'lynda') {
return done(null, {username: 'admin'});
}
return done(null, false);
}
));
passport.serializeUser(function(user, done) {
done(null, user.username);
});
passport.deserializeUser(function(username, done) {
done(null, {username: username});
});
module.exports = passport;
You're missing the session declaration, so req.session is undefined
app.use( express.cookieParser() );
app.use(express.session({ secret: 'my secret', cookie: { maxAge : 1200000 } }));
also, you seem to be mixing up the requires:
var passport = require('./auth');
I would change this to:
var auth = require('./auth');
to avoid confusion with the passport library
You don't have a session, so you can't do if (req.session.passport.user === undefined) ...
You probably didn't set the session after login

Categories

Resources