2016-09-28 13 views
64

Tôi có một ứng dụng sử dụng passport.js để đăng nhập người dùng thông qua facebook và đang cố gắng sử dụng phiên bản mysql-express để duy trì trạng thái đăng nhập của họ. Nếu tôi không bao gồm mã trình diễn-mysql-session, serializeUser hộ chiếu và chức năng deserializeUser sẽ bị phạt ... tuy nhiên khi tôi bỏ chú thích mã cố gắng lưu trữ phiên của họ với phiên-mysql-session, hàm deserializeUser không 't có được nhấn, và người dùng không bao giờ được đăng nhập đúng.Express-mysql-session ngăn ngừa hộ chiếu deserializeUser chạy

tập tin 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 

    } 

Vì vậy, nếu tôi nhận xét ra các 'cửa hàng' trong các đối tượng session ở trên, các chức năng hộ chiếu được đánh. Nếu tôi để lại dòng này un-nhận xét, các deserializeUser chức năng không nhận được hit.

chức năng Passport

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

EDIT

Mor Paz đề nghị tôi bao gồm một số các bản ghi từ khi tôi chạy máy chủ của tôi với các module debug. Dưới đây là nhật ký ngay trước và ngay sau khi người dùng được đăng. Người dùng nên được deserialized tại một số điểm gần này, nhưng không bao giờ được.

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 
+1

Bạn có thể thêm nhật ký từ nút không? Mô-đun 'express-mysql-session' sẽ xuất nhiều thông tin đăng nhập khi chạy trong DEBUG –

+0

Làm cách nào để chạy nút ở chế độ DEBUG? – user2796352

+0

Cài đặt mô-đun gỡ lỗi như được hiển thị trong liên kết này: https://github.com/visionmedia/debug và sau đó chạy ứng dụng của bạn bằng lệnh 'DEBUG = express-mysql-session * node your-app.js' –

Trả lời

1

Không thể sao chép vấn đề, vì vậy tôi đã chuẩn bị một ví dụ làm việc. [Github repo.]

nó crafted cho OpenShift, vì tôi thấy việc sử dụng môi trường biến (nó có thể được điều chỉnh một cách dễ dàng đối với trường hợp sử dụng khác).

tôi đã làm một số sửa đổi để các khái niệm ban đầu:

  1. thay thế cái cũ, không dùng nữa (thể hiện) kèm tập quán middleware.
  2. Sử dụng một Lớp thay vì self = this khái niệm
  3. Sử dụng Github thay vì Facebook cho người dùng đăng nhập ...
  4. bao gồm một số chức năng cơ bản bao gồm người dùng mới đến db
  5. Thiếu một số ban đầu mô-đun (có thể được bao gồm một cách dễ dàng)

Tôi hy vọng nó có thể hữu ích như là một điểm khởi đầu.

// .: 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; 
    } 
} 
Các vấn đề liên quan