在使用session.socket.io模块苦苦挣扎之后,我决定通过为socket.io设置授权来进行套接字会话链接。这是我的服务器:
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var io = require('socket.io');
var redis = require('redis');
var crypto = require('crypto');
var redisClient = redis.createClient();
var app = express();
// Session Tracking
var cookieParser = express.cookieParser('secret');
var RadisStore = require('connect-redis')(express);
var sessionStore = new RadisStore({
host: '127.0.0.1',
port: 6379,
db: 10,
client:redisClient
});
// Redis Client Used to store user Information
var redisUsersClient = redis.createClient();
const userDB = require('redis-user')(redisUsersClient);
var PORT = process.env.PORT || 3000,
HOST = process.env.HOST || 'localhost';
// We define the key of the cookie containing the Express SID
var EXPRESS_SID_KEY = 'express.sid';
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());
app.use(express.methodOverride());
app.use(cookieParser);
app.use(express.session({ store: sessionStore,
secret: 'SEKR37',
cookie: { httpOnly: true},
key: EXPRESS_SID_KEY
}));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', function(req, res){
if(!req.session.user)
res.redirect('/login')
else {
res.sendfile('chat.html')
}
});
app.get('/login', function(req, res){
res.render('login');
});
app.get('/register', function(req, res){
res.render('register');
});
app.get('/logout', function(req, res){
//console.log(req.session);
sessionStore.destroy(function(err){
console.log("there was an error: "+err);
});
req.session.destroy();
res.redirect('/login');
// redisUsersClient.hdel('users', req.session.user, function(err, reply){
// if(reply==1) {
//
// res.redirect('/login');
// }
// else
// res.send("you do not exist");
// });
});
app.post('/login',function(req, res){
var password = require('crypto').createHash('sha1WithRSAEncryption').update(req.body.password).digest('utf8');
var username = req.body.username+"@mychat.com";
//console.log(req.session);
userDB.validateUser(username, password, function(result){
if(result)
{
req.session.user = username;
req.session.status = 1;
req.session.isLogged = true;
req.session.save();
res.redirect('/');
}
else
{
res.send("Wrong Credential. Please <a href='/login'>Try Again</a>");
}
});
});
app.post('/register',function(req, res){
var username = req.body.username + "@mychat.com";
var password = require('crypto').createHash('sha1WithRSAEncryption').update(req.body.password).digest('utf8');
var verify = require('crypto').createHash('sha1WithRSAEncryption').update(req.body.verify).digest('utf8');
if(password==verify)
{
userDB.createUser(username, password, function(result) {
if (result) {
redisUsersClient.hset('users', username, password);
res.redirect('/');
} else {
res.send("could not create user, Something very unexpected happened");
}
});
}
else
{
res.send("Passwords do not match. please <a href='/register'>try again</a> " );
}
});
server = http.createServer(app);
io = io.listen(server);
/****
Maybe I have to set store for io?
****/
//io.set('store', sessionStore);
io.set('authorization', function (data, accept) {
if(!data.headers.cookie) {
return accept('No cookie transmitted.', false);
}
console.log(sessionStore);
cookieParser(data, {}, function(parseErr) {
if(parseErr) { return accept('Error parsing cookies.', false); }
var sidCookie = (data.secureCookies && data.secureCookies[EXPRESS_SID_KEY]) ||
(data.signedCookies && data.signedCookies[EXPRESS_SID_KEY]) ||
(data.cookies && data.cookies[EXPRESS_SID_KEY]);
console.log(sidCookie);
// Then we just need to load the session from the Express Session Store
sessionStore.load(sidCookie, function(err, session) {
// And last, we check if the used has a valid session and if he is logged in
console.log(session);
if (err || !session) {
accept('Error', false);
}
else {
// If you want, you can attach the session to the handshake data, so you can use it again later
data.session = session;
//console.log('success');
accept(null, true);
}
});
});
});
io.on('connection', function (socket) {
socket.on('add-user',function(data){
console.log(data.username);
clients.username = data.username;
//console.log(clients);
socket.broadcast.emit('entrance', data.username + ' has connected');
io.sockets.emit('add-user',{clients:clients});
});
socket.on('disconnect', function(){
delete clients[session.user];
io.sockets.emit('add-user',{clients:clients})
});
});
server.listen(PORT, HOST, null, function() {
console.log('Server listening on port %d in %s mode', this.address().port, app.settings.env);
});
这是我的客户:
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- <script type='text/javascripts', src='/javascripts/client.js'></script> -->
<link rel='stylesheet', href='/stylesheets/style.css'>
<script>
jQuery(document).ready(function () {
var log_chat_message = function (message, type, divId) {
var li = jQuery('<li />').text(message);
if (type === 'system') {
li.css({'font-weight': 'bold','color': '#F00','cursor':'pointer'});
} else if (type === 'leave' || type === 'error') {
li.css({'font-weight': 'bold', 'color': '#F00'});
}
jQuery('#'+divId).append(li);
};
// connect to the socket server
var socket = io.connect();
socket.on('error', function (reason){
console.error('Unable to connect Socket.IO', reason);
});
socket.on('welcome',function(data){
alert("yooooo");
var username = data.username.substr(0,data.username.indexOf('@'));
var message = "Welcome " + username ;
log_chat_message(message, 'system','messages');
socket.emit('add-user',{username: username});
});
socket.on('entrance', function(data){
//var message = data.username.substr(0,data.username.indexOf('@')) + " joined the chat";
log_chat_message(data, 'system','messages');
});
socket.on('add-user', function(data){
jQuery.each(data, function(key, value){
console.log(value.username);
log_chat_message(value.username, 'system','users-list');
})
});
jQuery('#message_input').keypress(function (event) {
if (event.which == 13) {
socket.emit('chat', {message: jQuery('#message_input').val()});
jQuery('#message_input').val('');
}
});
jQuery('#users-list li').on('click','li',function(){
alert('hi');
});
jQuery('#users-list li').click(function () {
var index = $(this).index();
var text = $(this).text();
alert('Index is: ' + index + ' and text is ' + text);
jQuery('#user').val('');
socket.emit('request', {username: jQuery('#user').val()});
});
});
</script>
<style type = 'text/stylesheet'>
#users-list li {
cursor:pointer;
}
</style>
</head>
<body>
<a href='/logout'>Log Out</a>
<div id="wrapper" style="width:80%;margin:0 auto;">
<!-- <input type="text" name="user" id="user"/>
<button id="submit" value="submit">Submit</button> -->
<div id='mainContaner' style="width:600px;height:400px;margin:0 auto;">
<div id="online-users" style="width:150px;float:left;height:400px;padding:20px;border:1px black solid;">
<ul id="users-list" style="list-style:none"></ul>
</div>
<div id= "container" style="width:350px;float:left;height:400px;padding:20px;overflow-y:scroll;border:1px black solid;">
<ul id='messages' style="list-style:none"></ul>
</div>
<input type="text" name="message_input" id='message_input' style="width:390px;height:30px;margin-left:193px;margin-top:5px;"/>
</div>
</div>
</body>
但是,我收到握手错误。我知道我无法通过加载会话存储来获取会话,这就是错误发生的原因。
请告知
答案 0 :(得分:0)
你应该替换这一行
sessionStore.load(sidCookie, function(err, session) {})
这一行
sessionStore.get(sidCookie, function(err, session) {})
这是因为connect-redis中没有方法加载。只有获取方法
此外,当您在套接字中访问会话时,可以使用socket.handshake.session.user