Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js SocketIO+;MySQL身份验证_Node.js_Authentication_Websocket_Socket.io - Fatal编程技术网

Node.js SocketIO+;MySQL身份验证

Node.js SocketIO+;MySQL身份验证,node.js,authentication,websocket,socket.io,Node.js,Authentication,Websocket,Socket.io,我试图通过socketIO通过MySQL数据库进行身份验证。我已经建立了连接,可以毫无问题地查询结果,但由于某种原因,我无法将用户是否经过身份验证传递到socketio的连接部分。我的想法是我的应用程序有主机和查看器。如果在QueryString中未发送密码就连接到应用程序,则应用程序将假定其为查看器并接受连接。如果发送了密码,将根据DB检查密码并接受/拒绝连接。我希望将一个变量传递到连接中,以便在我的应用程序事件中使用它。这是到目前为止我所拥有的,但显然数据。query['ishost']没有

我试图通过socketIO通过MySQL数据库进行身份验证。我已经建立了连接,可以毫无问题地查询结果,但由于某种原因,我无法将用户是否经过身份验证传递到socketio的
连接
部分。我的想法是我的应用程序有主机和查看器。如果在
QueryString
中未发送密码就连接到应用程序,则应用程序将假定其为查看器并接受连接。如果发送了密码,将根据DB检查密码并接受/拒绝连接。我希望将一个变量传递到
连接中
,以便在我的应用程序事件中使用它。这是到目前为止我所拥有的,但显然
数据。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
变量是握手数据,其中包含可以使用的请求头和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);
除非您的浏览器支持,否则客户端需要一个Base64库


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

非常有效。是的,我会调查passport.js。谢谢你的帮助。我不确定,我通常会避免使用闪存插座来优化我的服务器配置