Express-mysql-session preventing passport deserializeUser from running
It was impossible to replicate the problem, so I prepared a working example. [Github repo.]
Its crafted for Openshift, since I saw the usage of its environment variables (it can be adapted with ease for other use cases).
I did some modifications to the original concept :
- Replaced the old, deprecated (express) bundled middleware usages.
- Using a Class instead of the
self = this
concept - Using Github instead of Facebook for the user login...
- Included some basic functions to include new users to the db
- Missing some original modules (can be included with ease)
I hope it can be useful as a starting point.
// .: DB Configuration :.const mysql = require('mysql'); var dbconf = {host:process.env.OPENSHIFT_MYSQL_DB_HOST,port:process.env.OPENSHIFT_MYSQL_DB_PORT,user:process.env.OPENSHIFT_MYSQL_DB_USERNAME,password:process.env.OPENSHIFT_MYSQL_DB_PASSWORD,database:process.env.OPENSHIFT_APP_NAME,socket:process.env.OPENSHIFT_MYSQL_DB_SOCKET}} const dbconn = mysql.createConnection(dbconf); /*or create a pool*/ dbconn.connect();// .: Express & Other Middleware Modules :.var express = require('express');var path = require('path');var bodyParser = require('body-parser');var methodOverride = require('method-override');var cookieParser = require('cookie-parser');var serveStatic = require('serve-static');// .: Sessions :.var passport = require('passport');var GitHubStrategy = require('passport-github2');var session = require('express-session');var MySQLStore = require('express-mysql-session')(session);var sessionStoreConf = { connectionLimit:1,checkExpirationInterval:900000,expiration:86400000, createDatabaseTable:true,schema:{tableName:'LoginRequests',columnNames:{session_id:'loginID',expires:'expires',data:'data'}}};var sessionStore = new MySQLStore(sessionStoreConf,dbconn);// .: Server (class) :.class Server { constructor(port, ip){ this.app = express(); this.app.use(cookieParser('secret')); this.app.use(session({ key:'session_cookie_name', secret:'secret', cookie:{maxAge:3600000,secure:false}, store: sessionStore, resave:false, saveUninitialized:false })); this.app.use(passport.initialize()); this.app.use(passport.session()); this.app.use(serveStatic(path.join(__dirname,'public'))) this.app.listen(port,ip,function(){console.log('[i] Application worker started.');}); //require('./routes/site.js'); //~Example (routes/site.js) : this.app.get("/",function(req,res){res.send("<a href='./auth/github'>Click here to login (GitHub)</a>");}) this.app.get('/auth/github',passport.authenticate('github',{scope:['user:email']})); this.app.get('/auth/github/callback',passport.authenticate('github',{failureRedirect:'/'}),function(req,res){res.redirect('/success');}); // route for valid logins this.app.get('/success', function(req, res){ if(req.user){ console.log(req.user); res.send(req.user); } else{ res.redirect('/login'); } }); // route to check the sessionStore table entries in the browser this.app.get('/sessions',function(req,res){ dbconn.query("SELECT * FROM LoginRequests",function(err,rows){ if(err){console.log(err);}else{ if(rows.length!=0){ res.send(JSON.stringify(rows)); console.log(rows); }else{res.send("No LoginRequests found");} } }); }); //require('./config/passport.js')(passport); //~Example (config/passport.js) : passport.use(new GitHubStrategy( {clientID:"clientID",clientSecret:"clientSecret",callbackURL:"callbackURL"}, function(token, tokenSecret, user, cb){CheckUser('github',user,cb);} )); }}const server = new Server(process.env.OPENSHIFT_NODEJS_PORT,process.env.OPENSHIFT_NODEJS_IP);// .: Passport : Serialize & Deserialize User :.passport.serializeUser(function(user, done){ console.log('[passport] serializeUser'); done(null,user.id);});passport.deserializeUser(function(id, done) { console.log('[passport] deserializeUser'); dbconn.query("SELECT * FROM Users WHERE id=?",[id],function(err,rows){ if(err){console.log(err);}else{ if(rows.length!=0){ done(err,rows[0]); } else{ done(err,null); } } });});//:Check if user exists:function CheckUser(platform,user,cb){ dbconn.query("SELECT * FROM Users WHERE id=?",[user.id],function(err,rows){ if(err){console.log(err); cb(err,null);}else{ if(rows.length!=0){cb(null,user);} else{CreateUser(platform,user,cb);} } });} //:Create new user:function CreateUser(platform,user,cb){ switch(platform){ case "github": var newUserObj = {id:user.id,platform:platform,email:user.emails[0].value}; dbconn.query("INSERT INTO Users SET ?",newUserObj,function(err){ if(err){console.log(err); cb(err,null);}else{cb(null,user);} }); break; default: console.log("[error] (createUser) : platform not implemented :",platform); cb(err,null); break; }}