Express-mysql-session verhindert, dass Passport deserializeUser ausgeführt wird

Lesezeit: 7 Minuten

Benutzer-Avatar
Benutzer2796352

Ich habe eine App, die Passport.js verwendet, um Benutzer über Facebook anzumelden, und versuche, Express-Mysql-Session zu verwenden, um ihre Anmeldezustände beizubehalten. Wenn ich den Express-Mysql-Session-Code nicht einfüge, funktionieren die Passport-Funktionen serializeUser und deserializeUser einwandfrei nicht getroffen, und der Benutzer wird nie richtig angemeldet.

server.js-Datei

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 

    }

Wenn ich also die Option “Speichern” im obigen Sitzungsobjekt auskommentiere, werden die Passport-Funktionen getroffen. Wenn ich diese Zeile unkommentiert lasse, wird die Funktion deserializeUser nicht getroffen.

Passfunktionen

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]);
        });
    });

BEARBEITEN

Mor Paz schlug vor, dass ich einige der Protokolle einfüge, wenn ich meinen Server mit dem Debug-Modul betreibe. Nachfolgend sind die Protokolle direkt vor und unmittelbar nach der Serialisierung des Benutzers aufgeführt. Der Benutzer sollte irgendwann in der Nähe deserialisiert werden, ist es aber nie.

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

  • Können Sie die Protokolle von Node hinzufügen? Das express-mysql-session -Modul sollte viele Protokollinformationen ausgeben, wenn es in DEBUG ausgeführt wird

    – Mor Paz

    3. Oktober 2016 um 12:20 Uhr


  • Wie führe ich den Knoten im DEBUG-Modus aus?

    – Benutzer2796352

    4. Oktober 2016 um 23:09 Uhr

  • Sind Sie sicher, dass die Verbindung zu mysql erfolgreich etabliert? Verwenden connection.connect() und fügen Sie einen Rückruf mit einem err-Argument zum Aufruf von hinzu connect um sicherzustellen, dass die Verbindung problemlos hergestellt wird. *PS: Verwenden Sie tatsächlich Port 3307 zu? weil mysql standardmäßig ist 3306

    – Omar A

    5. Oktober 2016 um 15:55 Uhr

  • Ich habe diese Module, die mit diesen Versionen gut zusammenarbeiten: Express 3.0, Passport 0.3, Express-Session 1.11, Express-Mysql-Session 1.2. Ich kann Ihren Fehler nicht replizieren, aber mir fehlen die Versionsinformationen, wie sowie Ihre Passstrategien zum An- und Abmelden. Können Sie ein Gist- oder Github-Repo bereitstellen, in dem der Fehler repliziert werden kann?

    – Larry Turtis

    16. Oktober 2016 um 20:50 Uhr

  • @user2796352 Hast du eine Lösung für dieses Problem gefunden?

    – Sagar V

    7. Juli 2017 um 6:52 Uhr

Es war unmöglich, das Problem zu replizieren, also habe ich ein funktionierendes Beispiel vorbereitet. [Github repo.]

Es ist hergestellt für Openshiftda ich die Verwendung seiner gesehen habe Umgebung Variablen (kann problemlos für andere Anwendungsfälle angepasst werden).

Ich habe einige Änderungen am ursprünglichen Konzept vorgenommen:

  1. Ersetzt die alten, veralteten (Express) gebündelten Middleware-Verwendungen.
  2. Verwendung einer Klasse anstelle von self = this Konzept
  3. Verwenden Github statt Facebook für die Benutzeranmeldung…
  4. Einschließlich einiger grundlegender Funktionen, um neue Benutzer in die Datenbank aufzunehmen
  5. Es fehlen einige Originalmodule (können problemlos hinzugefügt werden)

Ich hoffe, es kann als Ausgangspunkt nützlich sein.

 // .: 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("https://stackoverflow.com/",function(req,res){res.send("<a href="https://stackoverflow.com/questions/39758973/./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:"https://stackoverflow.com/"}),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;
  }
}

1019900cookie-checkExpress-mysql-session verhindert, dass Passport deserializeUser ausgeführt wird

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy