SocketIO + MySQL的身份验证 [英] SocketIO + MySQL Authentication

查看:261
本文介绍了SocketIO + MySQL的身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过以上认证socketIO一个MySQL数据库。我已经建立了连接,并可以在没有问题查询结果时,但由于某些原因,我不能传递用户是否被认证成连接 socketio的一部分。这个想法是我的应用程序具有主机和观众。如果连接到应用程序,而不在查询字符串应用程序发送一个密码,假设它的观众并接受连接。如果密码被发送,这是对DB检查,接受/拒绝连接。我想要一个变量传递到连接这样我就可以用它我的应用程序的事件中。以下是我迄今为止但显然 data.query ['ishost'] 不传递到应用程序。

I am trying to authenticate over a MySQL DB via socketIO. I have established the connection and can query results without an issue, but for some reason I cannot pass whether or not the user is authenticated into the connection part of socketio. The idea is my app has hosts and viewers. If connecting to the app without sending a password in the QueryString the app assumes its a viewer and accepts connection. If a password is sent, it is checked against the DB and accepts/rejects the connection. I want a variable to pass into the connection so I can use it inside of my apps events. Here's what I have so far but apparently the data.query['ishost'] isn't passing into the app.

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访问。但由于某些原因,它不是将其通过应用程序。任何帮助是AP preciated,谢谢你。

Writing to the data.query makes it accessible through handshakeData. But for some reason its not passing it through the app. Any help is appreciated, thank you.

推荐答案

您正在接近,但我建议在设置一个查询字符串参数设置请求头。在您的授权功能数据变量是一个包含请求头,你可以用cookie信息握手数据。下面是与设置一个cookie的例子:

You're close, though I'd recommend setting a request header over setting a query string param. The data variable in your authorization function is handshake data that contains request header and cookie information you can use. Here's an example with setting a 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:

Before you call socket.connect, set a cookie with your auth / user info:

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);

除非你的浏览器支持 <$ c您将需要在客户端上一个Base64库$ C> BTOA()

要注意,这不是一个很好的鉴别结构是很重要的。直查询字符串或标题信息传递的用户凭据是不安全的。这种方法让你更接近一个更安全的方法,虽然。我建议寻找到一个auth库像passport.js或everyauth。您可以分在这个code利用会话信息这些库存储在运行您的支票。

It's important to note that this isn't a good authentication structure. Passing user credentials straight in either query strings or header information is not secure. This method gets you closer to a more secure method, though. I'd recommend looking into an auth library like passport.js or everyauth. You can sub-in this code to utilize the session information those libraries store in running your checks.

这篇关于SocketIO + MySQL的身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆