javascript mysql node.js express passport.js

javascript - Express-mysql-session evitando que se ejecute el pasaporte deserializeUser



node.js passport.js (1)

Tengo una aplicación que usa passport.js para iniciar sesión en los usuarios a través de Facebook, y estoy tratando de usar express-mysql-session para mantener sus estados de inicio de sesión. Si no incluyo el código express-mysql-session, las funciones de pasaporte serializeUser y deserializeUser funcionan bien ... sin embargo, cuando descomento el código que intenta almacenar su sesión con express-mysql-session, la función deserializeUser no funciona no te golpeen, y el usuario nunca inicia sesión correctamente.

archivo server.js

var express = require(''express''); var mysql = require(''mysql''); var passport = require(''passport''); var session = require(''express-session''); var MySQLStore = require(''express-mysql-session'')(session); if (typeof process.env.OPENSHIFT_MYSQL_DB_HOST === "undefined"){ var options = { host : ''localhost'', port : ''3307'', user : ''user'', password : ''password'', database : ''database'', socketpath: ''/var/run/mysqld/mysqld.sock'' } } else { var options = { 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 } }; var connection = mysql.createConnection(options); var sessionStore = new MySQLStore({ checkExpirationInterval: 900000,// How frequently expired sessions will be cleared; milliseconds. expiration: 86400000,// The maximum age of a valid session; milliseconds. createDatabaseTable: false,// Whether or not to create the sessions database table, if one does not already exist. connectionLimit: 1, schema: { tableName: ''LoginRequests'', columnNames: { session_id: ''loginID'', expires: ''expires'', data:''data'' } } }, connection); self.initializeServer = function() { self.app = module.exports = express(); self.app.configure(function() { self.app.set(''views'', __dirname + ''/public''); self.app.set(''view engine'', ''html''); self.app.engine(''html'', require(''hogan-express'')); self.app.enable(''view cache''); self.app.use(express.favicon()); self.app.use(express.logger(''dev'')); self.app.use(express.bodyParser()); self.app.use(express.methodOverride()); self.app.use(express.cookieParser(''secret'')); self.app.use(session({ key: ''session_cookie_name'', secret: ''secret'', cookie: {maxAge: 3600000, secure:false}, store: sessionStore, resave: false, saveUninitialized: false })); // required for passport self.app.use(passport.initialize()); self.app.use(passport.session()); // persistent login sessions self.app.use(express.static(path.join(__dirname, ''public''))); self.app.use(''/public'',express.static(__dirname, ''/public'')); self.app.use(self.app.router); //self.app.use(require(''stylus'').middleware(__dirname + ''/public'')); }); require(''./routes/site.js''); require(''./config/passport.js'')(passport); // pass passport for configuration }

Entonces, si comento la opción "almacenar" en el objeto de sesión anterior, las funciones del pasaporte se ven afectadas. Si dejo esta línea sin comentarios, la función deserializeUser no se ve afectada.

Funciones de pasaporte

passport.serializeUser(function(user, done) { console.log(''you have been serialized!''); done(null, user.id); }); // used to deserialize the user passport.deserializeUser(function(id, done) { console.log(''you have been deserialized!''); connection.query("SELECT * FROM Users WHERE id = "+id,function(err,rows){ done(err, rows[0]); }); });

EDITAR

Mor Paz sugirió que incluyera algunos de los registros de cuando ejecuto mi servidor con el módulo de depuración. A continuación se muestran los registros justo antes e inmediatamente después de que el usuario se serialice. El usuario debe ser deserializado en algún momento cerca de esto, pero nunca lo es.

GET /auth/facebook 302 81ms - 412b express-mysql-session:log Getting session: oNcJ4UapxCY_zKOyfSBTUWaVhaNZuFRq +356ms you are a user! you have been serialized! express-mysql-session:log Setting session: tgRPY-Mb1VDP2zaSMOFhlf_IWFhVpTia +798ms express-mysql-session:log Getting session: tgRPY-Mb1VDP2zaSMOFhlf_IWFhVpTia +6ms GET /auth/facebook/callback? code=AQCWPvA5ZRMYoTueW6_wWU49Up5ggjW68ufOtiYkU5IzhRjSNyyWnzlQVprgQo_uubQkEVvNI0yo53ET3cWBnDAHUGmAXPBy_ITEmC-biE2KEGEr0iCm_cqjuG90nnePY-k9U2oFUbX2kvLgMeM0kZ-094EHiU_NJjmAJNj6mzTkSE47935RhJy0Tba_sYS88_C0N3kn5f5kcoTC4KsgW1gBHWWJAwZ68Lj94ffVe2hN97580CtzEpJa0wwQHwTBYfmjQ0NfUdx07m4rXW9R7PR06aHDcUDrYqR9Kb0LWq4sZLbQjV5rI7gzkWG-huhq7IY 302 825ms - 72b express-mysql-session:log Setting session: Xo9OjfmJzTFp1CSF6srLi_UyxTCLg-EI +56ms express-mysql-session:log Getting session: Xo9OjfmJzTFp1CSF6srLi_UyxTCLg-EI +23ms express-mysql-session:log Getting session: Xo9OjfmJzTFp1CSF6srLi_UyxTCLg-EI +2ms GET /profile 200 84ms - 4.22kb


Era imposible replicar el problema, así que preparé un ejemplo de trabajo. [Repositorio de Github]

Está diseñado para Openshift , ya que vi el uso de sus variables de entorno (se puede adaptar con facilidad para otros casos de uso).

Hice algunas modificaciones al concepto original:

  1. Reemplazó los viejos usos de middleware en desuso (obsoletos).
  2. Usar una clase en lugar del self = this concepto
  3. Usando Github en lugar de Facebook para el inicio de sesión del usuario ...
  4. Incluye algunas funciones básicas para incluir nuevos usuarios a la base de datos
  5. Faltan algunos módulos originales (se pueden incluir con facilidad)

Espero que pueda ser útil como punto de partida.

// .: 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; } }