2016-01-14 102 views
1

前言:我是node.js,express,socket.io等等的新手。我意識到我的代碼有點麻煩,需要分解成模塊等 - 但我還沒有這樣做,因爲我試圖讓認證部分先工作。我已經搜索了所有的stackoverflow和其他網站。我找到了一些很有前途的例子,但我無法使它工作。express和socket.io身份驗證 - 如何檢索cookie /會話信息?

我跟着幾個教程來創建我的快速應用程序,它允許用戶註冊,登錄和查看他們的詳細信息。我也跟着一個教程,幫助我做一個基本的socket.io聊天。我想要做的是將它們結合起來,讓用戶登錄,然後重定向到聊天應用程序。我遇到的問題是,當我重定向它們時,我無法在事物的socket.io端知道「他們是誰」。目前我已經設置好了,所以你必須輸入你的名字進行聊天 - 我希望它從會話中獲取信息並使用它。

當前用戶登錄時,它確實設置了一個cookie(我可以在控制檯中查看它)。所以我知道cookie在那裏。它還將信息設置到MongoStore中。我已經使用db.collection.find()驗證了這一點。

這是我到目前爲止的代碼。如果有任何專家可以幫助我找到一種方法將會話信息傳遞給socket.io,我將非常感激!

var mongo = require('mongodb').MongoClient; 
var bodyParser = require('body-parser'); 
var bcrypt = require('bcryptjs'); 
var csrf = require('csurf'); 
var path = require ('path'); 
var express = require('express'); 
var mongoose = require('mongoose'); 
var uniqueValidator = require('mongoose-unique-validator'); 
var session = require('express-session'); 
var moment = require('moment'); 
var now = moment().format('L'); 
var http = require('http'); 



var MongoStore = require('connect-mongo')(session); 


var Schema = mongoose.Schema; 
var ObjectId = Schema.ObjectId; 

UserSchema = new Schema({ 
    //id: ObjectId, 

    firstName: String, 
    lastName: String,  
    username: { 
     type: String, 
     unique: true, 
     uniqueCaseInsensitive:true 
    }, 
    password: String, 
    email: { 
     type:String, 
     unique: true, 
     uniqueCaseInsensitive:true 
    }, 
    accountType: String, 
    accountStatus: String, 
    acctActivation:{ 
     type:String, 
    unique:true 
}, 
joinDate: String 

}); 
UserSchema.plugin(uniqueValidator,{ message: 'Error, {PATH} {VALUE} has already been registered.\r' }); 
var User = mongoose.model('User', UserSchema); 

var app = express(); 
app.engine('ejs', require('ejs').renderFile); 

app.locals.pretty = true; 

//connect to mongo 
mongoose.connect('mongodb://localhost/myUserDb'); 

//create server 

var server = http.createServer(app).listen(3000); 
var client = require('socket.io')(server); 
console.log('listening on port 3000'); 


//middleware 
app.use(express.static('public')); 
app.use(bodyParser.urlencoded({extended:true})); 


app.use(session({ 
    secret: 'mysecret!', 
    resave:false, 
    saveUninitialized: false, 
    stringify:true, 
    store: new MongoStore({ 
    url: 'mongodb://127.0.0.1/sid2' 

    }) 

})); 

app.use(csrf()); 

app.use(function(req,res,next){ // check to see if user already has a session, if so, query mongodb and update the user object 
    if(req.session && req.session.user){ 
     User.findOne({email: req.session.user.email}, function(err, user){ 
      if(user){ 
       req.user = user; 
       delete req.user.password; // remove password field from session 
       req.session.user = req.user; 
       res.locals.user = req.user; 
      } 
      next(); 
     }); 
    }else{ 
     next(); 
    } 
}); 

function requireLogin(req,res,next){ // check to see if user is logged in, if not, boot em 
    if(!req.user){ 
     res.redirect('/login'); 
    }else{ 
     next(); 
    } 
}; 
function requireAdmin(req,res,next){ // check to see if accountType = Developer (or admin later) - if not, send them to dashboard 
    if(req.user.accountType !== 'Developer'){ 
     res.redirect('/dashboard'); 
    }else{ 
     next(); 
    } 
}; 
app.get('/', function(req, res){ 
    if(req.user){ 
      res.render('dashboard.ejs'); 
    }else{ 
      res.render('index.ejs'); 
    } 

}); 

app.get('/register', function(req,res){  
    res.render('register.ejs', {csrfToken: req.csrfToken(), 
    error:false}); 
}); 

app.post('/register', function(req,res){   
    var hash = bcrypt.hashSync(req.body.password, bcrypt.genSaltSync(10)); 

    var user = new User({ 
     firstName: req.body.firstName, 
     lastName: req.body.lastName, 
     username: req.body.username, 
     password: hash, 
     email: req.body.email, 
     accountType: 'Standard', 
     accountStatus: 'Active',   
     joinDate: now 
    }); 

    user.save(function(err){ 
     if(err){ 
      console.log(err); 

      res.render('register.ejs', {csrfToken: req.csrfToken(), 
       error: err}); 

    }else{ 
     req.session.user = user; 
     res.redirect('/dashboard'); 
    } 

    }); 

}); 

app.get('/login', function(req,res){ 

    res.render('login.ejs', { 
     csrfToken: req.csrfToken(),error:false}); 
}); 


app.post('/login', function(req, res){ 
    User.findOne({username: {$regex: new RegExp('^' + req.body.username, 'i')}}, function(err, user){ 
     if(!user){ 

      res.render('login.ejs', {error: 'Invalid username or password combination.', 
      csrfToken: req.csrfToken()}); 
     }else{ 
      if(bcrypt.compareSync(req.body.password, user.password)){ 

       req.session.user = user; 

       res.redirect('/chat'); 
      }else{ 

       res.render('login.ejs', {error: 'Invalid username or password combination.', 
       csrfToken: req.csrfToken()}); 
      } 
     } 
    }); 
}); 

app.get('/dashboard', requireLogin, function(req,res){ 
     res.render('dashboard.ejs'); 
}); 
app.get('/chat', requireLogin, function(req,res){ 
     res.render('chat.ejs'); 
}); 
app.get('/admin', requireLogin, requireAdmin, function(req,res){ //required logged in AND admin status 
    // var userlist = User.find({}); 

    User.find({},{},function(err,docs){ 

     res.render('admin.ejs',{ "userlist": docs 

     }); 

    }) ; 



     // res.render('admin.ejs'); 
}); 

app.get('/logout', function(req,res){ 
    req.session.reset(); 
    res.redirect('/'); 
}); 

mongo.connect('mongodb://127.0.0.1/chat', function(err,db){ 
    if(err) throw err; 

client.on('connection', function(socket){ 

    var col = db.collection('messages'); 
    sendStatus = function(s){ 
     socket.emit('status', s); 
    }; 

    //emit all messages (shows old room data) 
    col.find().limit(100).sort({_id: 1}).toArray(function(err, res){ 
     if(err) throw err; 
     socket.emit('output',res); 

    }); 

    //wait for input 
    socket.on('input', function(data){ 
     var name = data.name, 
     message = data.message, 
     whitespacePattern = /^\s*$/; 

     if(whitespacePattern.test(name) || whitespacePattern.test(message)){ 
      sendStatus('Name and message is required.'); 
     }else{ 
      col.insert({name: name, message: message}, function(){ 
       //emit latest message to all clients 

       client.emit('output', [data]); 

     sendStatus({ 
      message: "Message sent", 
      clear: true 
     }); 

      }); 
     } 

    }); 

}); 

}); 

回答

0

好的,所以我終於明白了。我使用express-session來設置cookie,然後使用名爲express-socket.io-session的模塊將其傳遞給socket.io。

從那裏,我可以使用:

var data = socket.handshake.session; console.log(data.user.username);

來獲取我所需要的值。所有這些日子都在搜索,這是一個非常簡單的解決方案。我想我只是需要一些睡眠!