passport js fails to maintain session when nodejs server restarts - node.js

I am using nodejs, passportjs, jwtoken and mongoose to develop an application. I am facing some critical situation and stuck since 2 days.
I have used passport js for server side authentication and jwtoken for persistent login. It works very well ,with regular situation. But I have faced an issue before 3 days ago that when I restart server passport js fails to maintain session or expire nodejs user session. I don't know how to revalidate and recreate new passport session in nodejs.
I have tried a lot but failed to recreate. I found this issue when I tried to restart server and from web application any request sent to server. When I tried to access req.user to get user data from session it throws me req.user is undefined.
I even tried to use connect-mongo to store session but it throws an error -
"Error: failed to deserialize user out of session".
I don't know how to deal with situation. Provide me guidelines to resolve this issue.
Please refer below source code.
config.js
var express = require("express");
var http = require("http");
var path = require("path");
var bodyParser = require("body-parser");
var cookieParser = require("cookie-parser");
var expressSession = require("express-session");
var methodOverride = require("method-override");
var morgan = require("morgan");
var passport = require("passport");
var randToken = require('rand-token');
var jwt = require("jsonwebtoken");
var mongoose = require("mongoose");
var app = express();
var useragent = require('express-useragent');
app.use(useragent.express());
require("./utils")(express, app, path);
require("./db");
app.set("port", process.env.PORT || 2000);
app.set("env", "development");
if (app.get("env") === 'production') {
process.env['RECAPTCHA_PRIVATE_KEY'] = **** ;
process.env['JWT_PRIVATE_KEY'] = **** ;
process.env['COOKIE_PRIVATE_KEY'] = **** ;
process.env['JWT_TIME_OUT'] = 60 * 60 * 24 * 30 * 1000; // 30 days
process.env['SECURE_COOKIES'] = true;
} else if (app.get('env') === 'staging') {
process.env['RECAPTCHA_PRIVATE_KEY'] = **** ;
process.env['JWT_PRIVATE_KEY'] = **** ;
process.env['COOKIE_PRIVATE_KEY'] = **** ;
process.env['JWT_TIME_OUT'] = 60 * 60 * 24 * 30 * 1000; // 30 days
process.env['SECURE_COOKIES'] = false;
} else if (app.get('env') === 'development') {
process.env['RECAPTCHA_PRIVATE_KEY'] = **** ;
process.env['JWT_PRIVATE_KEY'] = **** ;
process.env['COOKIE_PRIVATE_KEY'] = **** ;
process.env['JWT_TIME_OUT'] = 60 * 60 * 24 * 30 * 1000; // 30 days
process.env['SECURE_COOKIES'] = false;
}
app.enable('trust proxy');
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(expressSession({
secret: process.env.COOKIE_PRIVATE_KEY,
name: 'hz-app',
proxy: true,
resave: true,
saveUninitialized: true,
httponly: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(methodOverride('X-HTTP-Method-Override'));
var router = express.Router();
var expressJWT = require("express-jwt");
var allowAccess = expressJWT({
secret: process.env.JWT_PRIVATE_KEY,
userProperty: 'payload'
}).unless({
path: [
'/api/user/register',
'/api/user/useractivation',
'/api/user/authenticate',
'/api/user/checkEmail',
'/api/user/checkNickName',
'/api/user/resetPassword',
'/api/user/addip',
'/api/user/forgetPasswordRequest',
'/api/user/logout',
'/api/cms/getCms',
'/adminapi/admin/authnticate',
'/adminapi/admin/logout',
'/adminapi/common/getLanguageList',
'/api/common/getCurrencyList',
'/adminapi/common/getUserType',
'/api/newsSubscriber/create',
// '/api/newsSubcrib/create',
// '/adminapi/admin/userList',
// '/adminapi/admin/getUserType',
// '/adminapi/admin/userCreate',
// '/adminapi/admin/userEdit',
]
});
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type, Authorization');
next();
});
app.all(["/api/*", "/adminapi/*"], allowAccess, function(req, res, next) {
if (req.user) {
console.log("log in authorize obj for check");
console.log(JSON.stringify(req.user));
} else {
console.log("not authenticated (not log in)");
//res.clearCookie('hz-token');
//res.clearCookie('hz-token-admin');
}
var reqPath = req.path.split("/");
console.log('../app/data/routes/' + reqPath[2]);
app.use(require('../app/data/routes/' + reqPath[2]));
next();
});
app.get("/", function(req, res) {
//app.use(function (req, res) {
res.sendFile(basePath + "app/client/views/index.html");
});
app.get("/admin", function(req, res) {
res.sendFile(basePath + "app/admin/views/index.html");
});
//Development error handler will print stacktrace
if (app.get('env') === "development") {
router.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
router.use(function(err, req, res, next) {
res.status(err.status || 500);
});
http.createServer(app).listen(app.get('port'), function() {
console.log('Epsilon is listening on port ' + app.get('port'));
});
exports = module.exports = app;
user.js
var express = require('express');
var router = express.Router();
var Helper = require("../components/helper");
var bcrypt = require("bcryptjs");
var moment = require("moment");
var User = require('../models/user');
var passport = require("passport");
var localStrategy = require("passport-local"),
Startegy;
router
.route('/api/user/authenticate')
.post(
function (req, res, next) {
console.log(">> authentication process initiated");
passport.authenticate('user-local', function (err, user, info) {
if (err) {
return res.status(401).json({
status: 0,
code: 401,
type: "error",
message: err
});
}
if (!user) {
console.log("not user:");
console.log(user);
return res.status(401).json({
status: 0,
code: 401,
type: "error",
message: info
});
}
req.login(user, {}, function (err) {
if (err) {
return res.status(500).json({
status: 0,
code: 500,
type: "other",
err: 'could not login user'
});
}
NextProcessForGenerateWebToken();
var NextProcessForGenerateWebToken = function () {
if (err) {
return next(err);
}
var _res = user.generateJWT(user);
res.cookie('hz-token', _res, {maxAge: process.env.JWT_TIME_OUT, httpOnly: false});
res.status(200).json({
status: 1,
type: "success",
message: 'login successful',
res: {
link: user.link_id,
nick_name: user.nick_name
}
});
};
});
})(req, res, next);
});
/**
* Serialize user for passport authentication
*/
passport.serializeUser(function (user, done) {
console.log("serialize:>>"+user.id);
console.log(user);
done(null, user.id);
});
/**
* Deserialize user for passport authentication
*/
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
console.log("deserialize:>>"+user.id);
done(err, user);
});
});
/**
* Passport local authentication policy to validate email/username and passport
*/
passport.use('user-local', new localStrategy({
usernameField: 'txtSigninEmail',
passwordField: 'txtSigninPassword'
},
function (username, password, done) {
User.findOne({$or: [{email: username}, {nick_name: new RegExp('^' + username + '$', "i")}], user_type: 3, is_active: 1, is_close: 0}, function (err, user) {
if (!user) {
return done(null, false, {message: 'Incorrect username.'});
}
user.comparePassword(password, function (err, isMatch) {
if (err)
throw err;
if (!isMatch) {
return done(null, false, {message: 'Incorrect password.'});
}
return done(null, user);
});
});
}
));
module.exports = router;

Related

I keep getting "Login sessions require session support" when I try to use tokens

So I am following a tutorial on how to use JSON tokens and I am getting an error, it was working fine using sessions but I can't figure out why I am having trouble, it is the exact code
this is my authenticate.js file:
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const User = require("./models/user");
const JwtStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require("passport-jwt").ExtractJwt;
const jwt = require("jsonwebtoken"); // used to create, sign, and verify tokens
const config = require("./config.js");
exports.local = passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
exports.getToken = function (user) {
return jwt.sign(user, config.secretKey, { expiresIn: 3600 });
}; // config.secretKey is a string of random numbers
const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = config.secretKey;
exports.jwtPassport = passport.use(
new JwtStrategy(opts, (jwt_payload, done) => {
console.log("JWT payload:", jwt_payload);
User.findOne({ _id: jwt_payload._id }, (err, user) => {
if (err) {
return done(err, false);
} else if (user) {
return done(null, user);
} else {
return done(null, false);
}
});
})
);
exports.verifyUser = passport.authenticate("jwt", { session: false });
This is my app.js file (the main file):
const createError = require("http-errors");
const express = require("express");
const path = require("path");
const logger = require("morgan");
const config = require("./config");
const indexRouter = require("./routes/index");
const usersRouter = require("./routes/users");
const mongoose = require("mongoose");
const passport = require("passport");
const url = config.mongoUrl;
const connect = mongoose.connect(url, {
useCreateIndex: true,
useFindAndModify: false,
useNewUrlParser: true,
useUnifiedTopology: true,
});
connect.then(
() => console.log("Connected correctly to server"),
(err) => console.log(err)
);
const app = express();
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// app.use(cookieParser("12345-67890-09876-54321"));
app.use(passport.initialize());
app.use("/", indexRouter);
app.use("/users", usersRouter);
app.use(express.static(path.join(__dirname, "public")));
// 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");
});
module.exports = app;
this is the routes/users.js file (I believe the problem is here because I can sign-up (create new users) but I can't login with the same users)
const express = require("express");
const User = require("../models/user");
const passport = require("passport");
const authenticate = require("../authenticate");
const router = express.Router();
/* GET users listing. */
router.get(
"/",
function (req, res, next) {
res.send('send users')
}
);
router.post("/signup", (req, res) => {
User.register(
new User({ username: req.body.username }),
req.body.password,
(err, user) => {
if (err) {
res.statusCode = 500;
res.setHeader("Content-Type", "application/json");
res.json({ err: err });
} else {
if (req.body.firstname) {
user.firstname = req.body.firstname;
}
if (req.body.lastname) {
user.lastname = req.body.lastname;
}
user.save((err) => {
if (err) {
res.statusCode = 500;
res.setHeader("Content-Type", "application/json");
res.json({ err: err });
return;
}
passport.authenticate("local")(req, res, () => {
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.json({
success: true,
status: "Registration Successful!",
});
});
});
}
}
);
});
// I tried to add a console.log inside of the .post() route but it never reach it
router.post(
"/login",
passport.authenticate("local"),
(req, res) => {
const token = authenticate.getToken({ _id: req.user._id });
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.json({
success: true,
token: token,
status: "You are successfully logged in!",
});
}
);
router.get("/logout", (req, res, next) => {
if (req.session) {
req.session.destroy();
res.clearCookie("session-id");
res.redirect("/");
} else {
const err = new Error("You are not logged in!");
err.status = 401;
return next(err);
}
});
module.exports = router;
Basically, every time that i go to localhost:3000/users/login and send a POST request with the username and password, it tells me that I need to use express-session but I am trying to use tokens instead of session
The problem is caused when passport.authenticate('local') is called in routes/users.js file. It is a middleware that automatically calls req.login function in case correct username and password is provided.
The req.login() in turn, implements sessions in order to serialise the user in the session.
You can solve the issue by adding another parameter to passport.authenticate() as passport.authenticate('local', {session: false}. This ensures sessions are not implemented in the 'local' strategy and subsequently login can be performed.
Thanks, it helped me. You have to remove app.use(passort.session) from app.js and do
router.post('/login', passport.authenticate('local', { session: false }), (req, res) => {
var token = authenticate.getToken({ _id: req.user._id });
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json({ success: true, token: token, status: 'You are successfully logged in!' });
});

NodeJS POST Form always return 404

I've been running through a problem and I can not find out what it is. I am using Express for this.
I have an "addUser" form which has the following Pug form :
form(action='/adduser', method='POST')
and I have try POST method in the app.js that doesn't work :
app.post("/adduser", function (req, res, info, next){
console.log('This does not appear');
});
What I don't understand is why the following login POST method which is just right above the adduser works perfectly :
app.post("/login", passport.authenticate('local', {
// login things
});
NB : At the beginning, the /adduser was in a router and was also returning 404, that's why I tried to move it in app.js .
Feel free to ask any informations that you need.
Anthony.
FULL CODE
app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var escape = require('escape-html');
var stock = require('./routes/stock');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// Variables pour le système d'users
var flash = require('connect-flash');
var crypto = require('crypto');
/* Login script */
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var connection = require('./lib/dbconn');
var sess = require('express-session');
var Store = require('express-session').Store;
var BetterMemoryStore = require(__dirname + '/memory');
var store = new BetterMemoryStore({expires: 60 * 60, debug: true});
app.use(sess({
name: 'StockInfo Sess.',
secret: 'C3ci3stUnSup3rS3cr3t',
store: store,
resave: true,
saveUninitialized: true
}));
//======================================================================================================================
// Configs =============================================================================================================
//======================================================================================================================
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use('/stock', stock);
//passport Strategy -- the express session middleware before calling passport.session()
passport.use('local', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true //passback entire req to call back
}, function (req, username, password, done) {
if (!username || !password) {
return done(null, false, req.flash('message', 'All fields are required.'));
}
var escapeData = escape(username);
var comboPrenomNom = escapeData.split(".");
var prenom = comboPrenomNom[0].toLowerCase();
var nom = comboPrenomNom[1].toLowerCase();
connection.query("SELECT id, password, salt FROM users WHERE prenom = ? and nom = ?", [prenom, nom], function (err, rows) {
if (err) return done(req.flash('message', err));
if (!rows.length) {
return done(null, false, req.flash('message', 'Invalid username or password.'));
}
if (!(rows[0].password === crypto.createHash('sha256').update(rows[0].salt + escape(password)).digest('hex'))) {
return done(null, false, req.flash('message', 'Invalid username or password.'));
}
req.session.user = rows[0].id;
return done(null, rows[0].id);
});
}
));
passport.serializeUser(function (id, done) {
done(null, id);
});
passport.deserializeUser(function (id, done) {
connection.query("SELECT id, prenom, nom, hasChangedPass, rights FROM users WHERE id = " + id, function (err, rows) {
done(err, rows[0]);
});
});
//======================================================================================================================
// Routes ==============================================================================================================
//======================================================================================================================
app.get('/', function (req, res, next) {
res.redirect('/login');
});
app.get('/login', function (req, res) {
res.render('login/index', {
title: 'LogIn',
message: req.flash('message')
});
});
app.post("/login", passport.authenticate('local', {
successRedirect: '/stock',
failureRedirect: '/login',
failureFlash: true
}), function (req, res, info) {
res.render('login/index', {
'message': req.flash('message')
});
});
app.post("/adduser", function (req, res, info, next) {
if (req.body.prenom && req.body.nom && req.body.password) {
var prenom = escape(req.body.prenom).toLowerCase();
var nom = escape(req.body.nom).toLowerCase();
connection.query("SELECT * FROM users WHERE prenom = ? and nom = ?", [prenom, nom], function (err, rows) {
if (err) {
console.log(err);
}
if (!rows.length) {
var salt = generate_token(32);
var password = escape(req.body.password);
password = crypto.createHash('sha256').update(salt + '' + password).digest('hex');
connection.query("INSERT INTO users (prenom, nom, password, salt) VALUES (?, ?, ?, ?);", [prenom, nom, password, salt], function (err) {
if (err) {
console.log(err);
}
});
}
});
} else {
res.redirect('/stock/fromage');
}
});
app.get('/logout', function (req, res) {
req.session.destroy();
req.logout();
res.redirect('/login');
});
// 404
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 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', {title: err.status});
});
function hasRights(req, res, next) {
if (req.user.rights[0] == 1 || req.user.rights[1] == 2 || req.user.rights[2] == 2 || req.user.rights[3] == 2) {
return next();
}
res.redirect('/stock');
}
function isAuthenticated(req, res, next) {
if (req.session.user) {
if (req.user.hasChangedPass) {
return next();
} else {
res.redirect('/stock/initpass');
}
}
res.redirect('/login');
}
module.exports = app;
/login/register.pug
extends ../layout
block content
include ../templates/header
.wrapper
form(action='/adduser', method='POST')
h3 Nouvel utilisateur
div.form-row
div.form-group
input.form-control(type='text', placeholder='Prénom', name='prenom' required)
div.form-row
div.form-group
input.form-control(type='text', placeholder='Nom', name='nom' required)
div.form-row
div.form-group
input.form-control(type='text', placeholder='Mot de Passe', name='password', value= pass required)
div.form-row
div.form-group
button.form-control Créer
div.form-row
div.form-group
p= rights
In your /adduser route you have 4 parameters in the callback function: (req, res, info, next). Remove info and Express will find your route.
With four parameters Express interprets your handler function as an error handler, see more information here: https://expressjs.com/en/guide/error-handling.html. Because of that you get a 404, as the request is passed through the middleware chain into the 404 handler.

NodeJS app using CSRF for web and JWT for API does async.parallel out of order

When a logged-in user gets to a page through the browser using EJS I'm able to get the function to do what it's supposed to but when I use the API with Ionic using a logged in user with JWT, the async.parallel function doesn't "wait" to do things in order.
Here is my function:
console.log('1');
async.parallel([
function(callback){
buildAlertButtonsArray.getRealTestAlerts(req,function(arrayAlerts) {
console.log('2');
callback(null, arrayAlerts);
});
},
function(callback) {
if(req.decoded) //API
callback('API');
else //EJS
functions.aclSideMenu(req, res, function (acl) {callback(null, acl);}); //aclPermissions sideMenu
}
],function(err, results){
console.log('3');
})
when I login through the browsed on my console.log() is 1, 2, 3 but when I login through the API using JWT I get 1, 3, 2.
Here is my app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
var bluebird = require('bluebird');
//me
var mongoose = require('mongoose');
var db = mongoose.connection;
var cors = require('cors');
var session = require('client-sessions');
var flash = require('express-flash');
//.js file
var routesApi = require('./routes/api');
var routesEjs = require('./routes/ejs');
var routes = require('./routes/index');
//var login = require('./routes/authentication/login');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(cookieParser());
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: true })); //was FALSE by default. was TRUE for auth Template
// middleware
app.use(session({
cookieName: 'session',
secret: 'mysecret',
duration: 30 * 60 * 1000,
activeDuration: 30 * 60 * 1000,
httpOnly: true, //doesn't let javascript access cookies ever
secure: true, // only use cookies over https
ephemeral: true // delete this cookie when the browser is closed (nice when people use public computers)
}));
app.use(flash());
app.use(function(req, res, next){
res.locals.success_messages = req.flash('success_messages');
res.locals.error_messages = req.flash('error_messages');
next();
});
// use cors
app.use(cors());
app.use('/public', express.static(path.join(__dirname, 'public')));
app.use('/api', routesApi);
app.use('/', routes);
app.use('/', routesEjs);
//bluebird
mongoose.Promise = require('bluebird');
//connecting to database
mongoose.connect('mongodb://myip:2999/SMECS_database', { useMongoClient: true });
//if we connect successfully or if a connection error occurs
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
// yay!
});
// error handlers
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
Here is my Login function for both EJS using CSRF and API using JWT:
module.exports.postLogin = function(req, res, next) {
if (req.body.pushToken) { // run SMECS API
models.Users.findOne({
email: req.body.email.toLowerCase()
}, function (err, user) {
if (err) throw err;
if (!user) {
res.json({success: false, message: 'Authentication failed. User not found.'});
} else if (user) {
//check if password matches
if (!bcrypt.compareSync(req.body.pin, user.pin)) {
res.json({success: false, message: 'Authentication failed. Wrong password.'});
} else {
// if user is found and password is right
// create a token
var token = jwt.sign({user: user}, config.secret, {
//expiresIn: 1440 // expires in 24 hours
});
user.save(function (err) {
if (err) {
res.json({
success: false,
message: 'contact your system administrator. pushToken not saved'
});
} else {
// return the information including token as JSON
res.json({
success: true,
message: 'Welcome aboard!',
token: token,
userRoleID: user.userRoleID,
userRoleName: user.userRoleName,
userPrivilegeID: user.userPrivilegeID,
userPrivilegeName: user.userPrivilegeName,
firstName: user.firstName,
lastName: user.lastName,
email: user.email
});
}
});
}
}
});
}
else { //run SMECS EJS
models.Users.findOne({email: req.body.email.toLowerCase()}, function (err, user) {
if (!user || user.softDeleted !== null) {
//Parent Self Registration Login
models.ParentSelfRegistration.findOne({email: req.body.email.toLowerCase()}, function (err, parentSelfRegistration) {
if (!parentSelfRegistration) {
res.render('login', {error: "ERROR: Incorrect email or pin.", csrfToken: req.csrfToken()});
} else {
if (req.body.pin == parentSelfRegistration.pin) {
req.session.user = parentSelfRegistration;
res.redirect('/parentsSelfRegistration/registerParentStep1');
} else {
res.render('login', {error: "ERROR: Incorrect email or pin.", csrfToken: req.csrfToken()});
}
}
});
//END OF checks for users in UtilityUsers database
} else {
if (bcrypt.compareSync(req.body.pin, user.pin)) { // if user is found and password is right
req.session.user = user;
res.redirect('/dashboard');
//}
} else {
//res.status(400).send('Current password does not match');
res.render('login', {error: "ERROR: Incorrect email or pin.", csrfToken: req.csrfToken()});
//res.render('login', { error: "ERROR: Incorrect email or pin."});
}
}
});
}
};
Here is my ejs.js file:
//Dependencies
var express = require('express');
var routerEjs = express.Router();
var login = require('./authentication/login');
var auth = require('./authentication/auth');
var chooseAlert = require('./alerts/sendingReceiving/1.chooseAlert');
var login = require('./authentication/login');
var csrf = require('csurf');
routerEjs.use(csrf());
/* GET login page. */
routerEjs.get('/login', login.getLogin, function(req, res) {});
routerEjs.post('/login', login.postLogin, function(req, res) {});
routerEjs.get('/logout', login.getLogout, function(req, res) {});
module.exports = routerEjs;
and my api.js file:
//Dependencies
var express = require('express');
var routerApi = express.Router();
var login = require('./authentication/login');
var auth = require('./authentication/auth');
var chooseAlert = require('./alerts/sendingReceiving/1.chooseAlert');
routerApi.post('/login', login.postLogin, function(req, res) {});
routerApi.get('/chooseGroup', auth.auth, chooseAlert.showGroups, function(req, res) {});
routerApi.get('/alerts/sending/chooseAlert', auth.auth, chooseAlert.showAlerts, function(req, res) {});
/* Update pushToken ------------------------------------*/
routerApi.post('/updatePushToken', auth.auth, auth.pin, function(req, res) {});
module.exports = routerApi;
I figured out my problem. I was missing a NULL on my callback...
console.log('1');
async.parallel([
function(callback){
buildAlertButtonsArray.getRealTestAlerts(req,function(arrayAlerts) {
console.log('2');
callback(null, arrayAlerts);
});
},
function(callback) {
if(req.decoded) //API
callback(NULL, 'API');
else //EJS
functions.aclSideMenu(req, res, function (acl) {callback(null, acl);}); //aclPermissions sideMenu
}
],function(err, results){
console.log('3');
})

Passport js always shows Unauthorized

I am new to nodejs(v4.5) & express(v4) and i am trying to create login with passport js(local) . i tried a lot but i always get 401 error. I also checked forums but could not find the solution.
Express-session is v1.5.
This is my code:
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var bodyParser = require('body-parser');
var passport = require('passport');
var flash = require('connect-flash');
var base = require('./base');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
require('./config/passport')(passport);
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'vidyapathaisalwaysrunning',
resave: false,
saveUninitialized: true
} ));
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash());
app.use(function (req, res, next) {
req.rooturl = req.protocol + '://' + req.get('host') + '/';
next();
});
require('./routes/admin')(app, passport);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
db.js
var mysql = require('mysql');
var sqlConnection = function sqlConnection(sql, values, next) {
if (arguments.length === 2) {
next = values;
values = null;
}
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
port: 3306,
database : 'test'
});
connection.connect(function(err) {
if (err !== null) {
console.log("[MYSQL] Error connecting to mysql:" + err+'\n');
}
});
connection.query(sql, values, function(err) {
connection.end();
if (err) {
throw err;
}
// Execute the callback
next.apply(this, arguments);
});
}
module.exports = sqlConnection;
admin.js
var db = require('../config/db');
module.exports = function(app, passport){
app.get('/admin', function(req, res) {
res.render('login/admin', {
rooturl: req.rooturl,
title: 'Crud'
});
});
app.post('/admin', passport.authenticate('local-login'), function(req, res) {
res.json('5');
});
};
admin.ejs
$('#login').validate({
submitHandler: function(form){
var data = $(form).serialize();
$.ajax({
type:'post',
url: document.url,
//data: new FormData(form),
data: data,
processData: false,
cache: false,
success: function(d){
alert(JSON.stringify(d));
}
});
return false;
}
});
passport.js
var LocalStrategy = require('passport-localapikey').Strategy;
var db = require('./db');
module.exports = function(passport) {
// console.log('5');
passport.serializeUser(function(user, done) {
console.log('4');
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
db("SELECT * FROM user WHERE id = ? ",[id], function(err, rows){
console.log('6');
done(err, rows[0]);
});
});
passport.use('local-login',
new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, username, password, done) {
console.log(username);
db("SELECT * FROM user WHERE email = ? and password = ?",[username, password], function(err, rows){
console.log('2');
if (err)
return done(err);
if (!rows.length) {
return done(null, false, req.flash('loginMessage', 'No user found.'));
}
if(password != rows[0].password){
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
}
return done(null, rows[0]);
});
})
);
}

Passport.js remember me functionality

https://github.com/jaredhanson/passport-remember-me
passport.use(new RememberMeStrategy(
function(token, done) {
Token.consume(token, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
return done(null, user);
});
},
function(user, done) {
var token = utils.generateToken(64);
Token.save(token, { userId: user.id }, function(err) {
if (err) { return done(err); }
return done(null, token);
});
}
));
post
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
function(req, res, next) {
// issue a remember me cookie if the option was checked
if (!req.body.remember_me) { return next(); }
var token = utils.generateToken(64);
Token.save(token, { userId: req.user.id }, function(err) {
if (err) { return done(err); }
res.cookie('remember_me', token, { path: '/', httpOnly: true, maxAge: 604800000 }); // 7 days
return next();
});
},
function(req, res) {
res.redirect('/');
});
I'm trying to implement remember me feature (above) into my existing application but I couldn't make it. When I add RememberMeStrategy into my login.js, it throws
ReferenceError: RememberMeStrategy is not defined
error. What's missing here?
index.js
var rendering = require('../util/rendering');
var express = require('express');
var router = express.Router();
exports.home = function(req, res) {
res.render('index/index');
};
exports.userHome = function(req, res) {
res.render('index/user-home');
};
login.js
var crypto = require('crypto'),
passport = require('passport'),
passportRememberMe = require('passport-remember-me'),
passportLocal = require('passport-local'),
data = require('../models/auth')();
exports.registerPage = function (req, res) {
res.render('login/register', {username: req.flash('username')});
};
exports.registerPost = function (req, res) {
var vpw = req.body.vpw;
var pwu = req.body.pw;
var un = req.body.un;
req.flash('username', un);
if (vpw !== pwu) {
req.flash('error', 'Your passwords did not match.');
res.redirect('/register');
return;
}
req.checkBody('un', 'Please enter a valid email.').notEmpty().isEmail();
var errors = req.validationErrors();
if (errors) {
var msg = errors[0].msg;
req.flash('error', msg);
res.redirect('/register');
return;
}
var new_salt = Math.round((new Date().valueOf() * Math.random())) + '';
var pw = crypto.createHmac('sha1', new_salt).update(pwu).digest('hex');
var created = new Date().toISOString().slice(0, 19).replace('T', ' ');
new data.ApiUser({email: un, password: pw, salt: new_salt, created: created}).save().then(function (model) {
passport.authenticate('local')(req, res, function () {
res.redirect('/home');
})
}, function (err) {
req.flash('error', 'Unable to create account.');
res.redirect('/register');
});
};
exports.loginPage = function (req, res) {
res.render('login/index', {username: req.flash('username')});
};
exports.checkLogin = function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
if (err || !user) {
req.flash('username', req.body.un);
req.flash('error', info.message);
return res.redirect('/login');
}
req.logIn(user, function (err) {
if (err) {
req.flash('error', info.message);
return res.redirect('/login');
}
req.flash('success', 'Welcome!');
return res.redirect('/home');
});
})(req, res, next);
};
exports.logout = function (req, res) {
req.logout();
req.flash('info', 'You are now logged out.');
res.redirect('/login');
};
routes.js
var rendering = require('./util/rendering'),
indexController = require('./controllers/index'),
loginController = require('./controllers/login');
module.exports = function (app, passport) {
// Home
app.get('/', indexController.home);
app.get('/home', ensureAuthenticated, indexController.userHome);
// Auth
app.get('/register', loginController.registerPage);
app.post('/register', loginController.registerPost);
app.get('/login', loginController.loginPage);
app.post('/login', loginController.checkLogin);
app.get('/logout', loginController.logout);
// 'rendering' can be used to format api calls (if you have an api)
// into either html or json depending on the 'Accept' request header
app.get('/apitest', function(req, res) {
rendering.render(req, res, {
'data': {
'test': {
'testsub': {
'str': 'testsub hello world'
},
'testsub2': 42
},
'test2': 'hello world'
}
});
})
// Auth Middleware
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login');
}
}
server.js
var dbConfig;
try {
// Look for dev conf for local development
dbConfig = require('./config/db.dev.conf.js');
} catch(e) {
try {
// production conf?
dbConfig = require('./config/db.conf.js');
} catch(e) {
console.log('Startup failed. No db config file found.');
return false;
}
}
var knex = require('knex')({
client: 'mysql',
connection: dbConfig
}),
express = require('express'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
cookieSession = require('cookie-session'),
serveStatic = require('serve-static'),
expressValidator = require('express-validator'),
flash = require('connect-flash'),
swig = require('swig'),
passport = require('passport'),
passportRememberMe = require('passport-remember-me'),
passportLocal = require('passport-local'),
crypto = require('crypto'),
Bookshelf = require('bookshelf'),
messages = require('./util/messages');
var app = express();
Bookshelf.mysqlAuth = Bookshelf(knex);
app.use(cookieParser('halsisiHHh445JjO0'));
app.use(cookieSession({
keys: ['key1', 'key2']
}));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(expressValidator());
app.use(passport.initialize());
app.use(passport.session());
app.use(passport.authenticate('remember-me'));
app.use(flash());
app.use(serveStatic('./public'));
//app.use(express.favicon(__dirname + '/public/images/shortcut-icon.png'));
app.use(messages());
app.engine('html', swig.renderFile);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
require('./util/auth')(passport);
require('./routes')(app, passport);
app.listen(process.env.PORT || 3000);
console.log('Listening on port 3000');
That error is simply saying that you haven't defined the RememberMeStrategy function before calling it (you're using new but in Javascript that's just calling a function with a special variable called this). You need to require the module first, in this case:
var RememberMeStrategy = require('passport-remember-me').Strategy;
Just require it in the variable RememberMeStrategy
var RememberMeStrategy= require('passport-remember-me').Strategy;

Resources