express和socket.io身份验证 - 如何检索cookie /会话信息?

时间:2016-01-14 04:08:57

标签: node.js session authentication cookies socket.io

前言:我是node.js,express,socket.io以及所有这些的新手。我意识到我的代码有点混乱,需要分成模块等 - 但我还没有这样做,因为我试图让认证部分先工作。我搜索了遍布stackoverflow和其他网站。我找到了一些很有希望的例子,但我还是没能让它发挥作用。

我按照几个教程创建了我的快速应用程序,允许用户注册,登录和查看其详细信息。我还遵循了一个教程,帮助我做了一个基本的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
         });

          });
      }

    });

});

});

1 个答案:

答案 0 :(得分:0)

好的,所以我终于明白了。我使用快速会话来设置cookie,然后使用一个名为express-socket.io-session的模块将它传递给socket.io。

从那里,我能够使用:

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

检索我需要的值。所有这些天搜索,这是一个非常简单的解决方案。我想我只是需要一些睡眠!