SocketIO + MySQLauthentication

我试图通过socketIO在MySQL数据库上进行身份validation。 我build立了连接,可以查询结果没有问题,但由于某种原因,我不能通过是否用户被authentication到connection部分的socketio。 这个想法是我的应用程序有主机和观众。 如果连接到应用程序而不在QueryString发送密码,则该应用程序假定其为查看器并接受连接。 如果发送密码,则会对数据库进行检查并接受/拒绝连接。 我想要一个variables传入connection所以我可以在我的应用程序事件中使用它。 这是我迄今为止,但显然data.query['ishost']没有传入应用程序。

 sio.configure(function() { sio.set('authorization', function (data, accept) { UserID = data.query['username']; try { UserID = UserID.toLowerCase(); } catch(err) { return accept("No WebBot Specified. ("+err+")", false); } // if not sending a password, skip authorization and connect as a viewer if (data.query['password'] === 'undefined') { return accept(null, true); } // if sending a password, attempt authorization and connect as a host else { client.query( 'SELECT * FROM web_users WHERE username = "'+UserID+'" LIMIT 1', function selectCb(err, results, fields) { if (err) { throw err; } // Found match, hash password and check against DB if (results.length != 0) { // Passwords match, authenticate. if (hex_md5(data.query['password']) == results[0]['password']) { data.query['ishost'] = true; accept(null, true); } // Passwords don't match, do not authenticate else { data.query['ishost'] = false; return accept("Invalid Password", false); } } // No match found, add to DB then authenticate else { client.query( 'INSERT INTO web_users (username, password) VALUES ("'+UserID+'", "'+hex_md5(data.query['password'])+'")', null); data.query['ishost'] = "1"; accept(null, true); } client.end(); } ); // Should never reach this return accept("Hacking Attempt", false); } // Definitely should never reach this return accept("Hacking Attempt", false); }); }); 

写入data.query使其可以通过handshakeData访问。 但由于某种原因,它不通过应用程序。 任何帮助表示赞赏,谢谢。

你很近,但我build议通过设置查询string参数来设置请求标题。 授权function中的datavariables是握手数据,其中包含您可以使用的请求标头和Cookie信息。 这里有一个设置cookie的例子:

在服务器上

 io.configure(function() { io.set('authorization', function(handshake, callback) { var cookie, token, authPair, parts; // check for headers if (handshake.headers.cookie && handshake.headers.cookie.split('=')[0]=='myapp') { // found request cookie, parse it cookie = handshake.headers.cookie; token = cookie.split(/\s+/).pop() || ''; authPair = new Buffer(token, 'base64').toString(); parts = authPair.split(/:/); if (parts.length>=1) { // assume username & pass provided, check against db // parts[0] is username, parts[1] is password // .... {db checks}, then if valid.... callback(null, true); } else if(parts.length==1) { // assume only username was provided @ parts[0] callback(null,true); } else { // not what we were expecting callback(null, false); } } else { // auth failed callback(null, false); } }); }); 

在客户端

调用socket.connect 之前 ,请在auth / user info中设置一个cookie:

 function writeCookie(value, days) { var date, expires; // days indicates how long the user's session should last if (days) { date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); expires = "; expires="+date.toGMTString(); } else { expires = ""; } document.cookie = "myapp="+Base64.encode(value)+expires+"; path=/"; }; // for a 'viewer' user: writeCookie('usernameHere', 1); // for the 'host' user: writeCookie('usernameHere:passwordHere', 1); 

除非您的浏览器支持btoa()否则您需要在客户端使用Base64库。

重要的是要注意,这不是一个好的身份validation结构。 直接在查询string或标题信息中传递用户凭证是不安全的。 不过,这个方法让你更接近一个更安全的方法。 我build议看看像passport.js或everyauth auth库。 你可以在这个代码中使用这些库存储的会话信息来运行你的支票。