今天做到聊天室问题的时候,登录成功保存或更新mongodbsession信息,想要在socket对话的时候验证和获得session的信息,如果存在session,转发信息,否则返回一个提示并关闭socket连接。
关于mongodb存储session在之前已经讲述使用connect-mongo来管理session的信息,但是socket如何获得session的信息并且和前端的连接的socket handshake的cookie ID 一致。在网上找到了解决方案,不过只适合在connect-redis使用可以下载代码npm install session.socket.io预读代码,代码很少,我只修改了部分代码完成了想要的功能。代码如下:
01 | module.exports = function (io, sessionStore, cookieParser, key) { |
02 | key = key || 'connect.sid' ; |
04 | this .of = function (namespace) { |
06 | on: function (event, callback) { |
07 | return bind.call( this , event, callback, io.of(namespace)); |
12 | this .on = function (event, callback) { |
13 | return bind.call( this , event, callback, io.sockets); |
16 | this .getSession = function (socket, callback) { |
17 | cookieParser(socket.handshake, {}, function (parseErr) { |
18 | var sessionid = socket.handshake.cookies[key]; |
24 | sid = sessionid.split( ':' )[1].split( '.' )[0]; |
26 | sessionStore.get(sid, function (storeErr, session) { |
27 | var err = resolve(parseErr, storeErr, session); |
28 | callback(err, session); |
33 | function bind(event, callback, namespace) { |
34 | namespace.on(event, function (socket) { |
35 | this .getSession(socket, function (err, session) { |
36 | callback(err, socket, session); |
41 | function findCookie(handshake) { |
42 | return (handshake.secureCookies && handshake.secureCookies[key]) |
43 | || (handshake.signedCookies && handshake.signedCookies[key]) |
44 | || (handshake.cookies && handshake.cookies[key]); |
47 | function resolve(parseErr, storeErr, session) { |
48 | if (parseErr) return parseErr; |
49 | if (!storeErr && !session) return new Error ( 'could not look up session by key: ' + key); |
现在socket链接的时候使用如下代码
01 | var SessionSockets = require( './session.socket.io' ); |
02 | var sessionStore = new MongoStore({ |
03 | url:settings.mongodb.host |
05 | var cookieParser =express.cookieParser( 'world' ); |
08 | var sessionSockets = new SessionSockets(io,sessionStore,cookieParser, 'jsessionid' ); |
09 | sessionSockets.on( 'connection' , function (err,socket,session) { |
10 | console.log( '-session' ,session.jsessionid); |
终于,感觉上面的方法有些繁琐,于是另辟蹊径,果然找到了更加简易的方法,socket.io自带有一个握手验证方法authorization,这个方法在链接的时候验证是否登录成功,那我们可以根据会话成功修改成我们设定的sessionID,以便于我们在socket可以访问到。上代码:
02 | module.exports = function (io,sessionStore,cookieParser) { |
04 | io.set( 'authorization' , function (handshakeData, callback){ |
06 | handshakeData.cookie = cookie.parseCookie(handshakeData.headers.cookie) |
07 | var sessionid = handshakeData.cookie[ 'connect.sid' ]; |
14 | sid = sessionid.split( ':' )[1].split( '.' )[0]; |
16 | sessionStore.get(sid, function (error, session){ |
19 | callback(error.message, false ); |
24 | handshakeData.session = session; |
30 | callback( 'nosession' ); |
34 | io.on( 'connection' , function (socket) { |
35 | console.log( "Connection " + socket.id + " accepted." ); |
37 | console.log( '-session' ,socket.handshake.session.userid); |
40 | socket.on( 'message' , function (msg){ |
不过感觉最开始那种更全面点哈。特别是对cookie的类型获取验证
转自:http://my.oschina.net/antianlu/blog/187254