前言:我是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
});
});
}
});
});
});