2012-05-15 49 views
1

我想通过socketIO通过MySQL数据库进行身份验证。我建立了连接并可以查询结果而没有问题,但由于某种原因,我无法通过用户是否被认证到socketio的connection部分。这个想法是我的应用程序有主持人和观众。如果连接到应用程序时未在QueryString中发送密码,则该应用程序假定其为查看器并接受连接。如果发送密码,则会对数据库进行检查并接受/拒绝连接。我想要一个变量传入connection,这样我就可以在我的应用程序事件中使用它。以下是我目前为止的内容,但显然data.query['ishost']没有传入应用。SocketIO + MySQL身份验证

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访问。但由于某种原因,它没有通过应用程序传递。任何帮助表示赞赏,谢谢。

回答

5

你很近,但我建议设置一个请求头来设置查询字符串参数。授权功能中的data变量是握手数据,其中包含您可以使用的请求标头和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之前,请设置您的身份验证/用户信息一个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库。

重要的是要指出,这不是一个好的身份验证结构。直接在查询字符串或标题信息中传递用户凭证是不安全的。不过,这种方法让你更接近更安全的方法。我建议寻找像passport.js或everyauth这样的auth库。您可以在此代码中使用这些库在运行检查时存储的会话信息。

+0

很好用。我会看看passport.js。谢谢你的帮助。 –

+0

如果你回退到闪存套接字,这个工作会吗? – NightWolf

+0

我不确定,我通常会避免使用Flash套接字来简化我的服务器配置 –