Идентификация socket.io после установления соединения

Я работаю над небольшой многопользовательской игрой. Я хотел бы ввести аутентификацию. Я использую Node.js и Socket.io.

Когда пользователь приходит на главную страницу - я хочу, чтобы они присоединились к игре независимо от того, вошли ли они в систему или нет, но они не смогут ничего сделать в ней (только смотреть).

Как я могу затем пройти аутентификацию пользователя в уже открытом сокете?

Могу ли я сохранить аутентификацию, если они покинут сайт и вернутся? Можете ли вы передать файл cookie через веб-сокет?

ИЗМЕНИТЬ

Чтобы продолжить мой вопрос. Одна из возможных мыслей заключалась в том, чтобы предоставить соединение с веб-сайтами, а затем, когда они пытаются войти в систему, он передает имя пользователя и пароль в качестве сообщения в веб-узел.

client.on('onLogin', loginfunction);

Затем я мог взять имя пользователя и пароль, проверить базу данных, затем взять идентификатор сеанса сокета и передать его где-нибудь, чтобы сказать, что сеанс аутентифицирован для этого пользователя.

Это безопасно? Могу ли я по-прежнему использовать куки файлы в сокете, чтобы они могли вернуться? Есть ли способ в socket.io заявить, что сокет теперь аутентифицирован вместо ручной проверки каждого полученного сообщения?

Приветствия

Ответы

Ответ 1

Это не слишком сложно, но вы приближаетесь к нему неправильно. Пара вещей:

  • Вы не можете установить cookie с socket.io; однако вы можете получить значения cookie любого подключенного клиента в любое время. Чтобы установить cookie, вам нужно будет отправить новый ответ HTTP, то есть пользователь должен сначала отправить новый HTTP-запрос (например, обновить или перейти на новую страницу, что звучит для вас здесь не так).

  • Да: socket.io является защищенным (в той мере, в которой могут быть переданы любые данные).

Таким образом, вы можете сделать следующее:

В исходном подключении пользователя создайте файл cookie с уникальным идентификатором сеанса, например, сгенерированным из промежуточного программного обеспечения сеанса Express. Вам нужно будет настроить их, чтобы они не заканчивались на конце сеанса (в противном случае он истечет, как только они закроют браузер).

Затем вы должны создать объект для хранения идентификаторов сеанса cookie. Каждый раз, когда установлен новый файл cookie connect.sid, сохраняйте в своем новом объекте значение по умолчанию false (это означает, что пользователь был аутентифицирован сеансом, но не с помощью входа в систему)

При входе в систему пользователя отправьте сокет на сервер, где вы сможете аутентифицировать учетные данные для входа, а затем обновить объект идентификатора сеанса, который вы создали, для чтения истины (для входа в систему) для текущего идентификатора сокета.

Теперь, когда вы получаете новый HTTP-запрос, прочитайте файл cookie.sid и проверьте, истинно ли его значение в вашем объекте.

Он должен выглядеть примерно так:

var express = require('express'),
http = require('http'),
cookie = require('cookie');

var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);


app.use(express.cookieParser());
app.use(express.session({ 
    secret: 'secret_pw',
    store: sessionStore,
    cookie: { 
        secure: true,
        expires: new Date(Date.now() + 60 * 1000), //setting cookie to not expire on session end
        maxAge: 60 * 1000,
        key: 'connect.sid'
    }
}));

var sessionobj = {}; //This is important; it will contain your connect.sid IDs.

//io.set('authorization'...etc. here to authorize socket connection and ensure legitimacy


app.get("/*", function(req, res, next){
    if(sessionobj[req.cookies['connect.sid']]){
        if(sessionobj[req.cookies['connect.sid']].login == true){
            //Authenticated AND Logged in
        }
        else{
            //authenticated but not logged in
        }
    }
    else{
        //not authenticated
    }

});


io.sockets.on('connection', function(socket){
    sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid'].login = false;
    sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid'].socketid = socket.id;

    socket.on('login', function(data){
        //DB Call, where you authenticate login
        //on callback (if login is successful):
        sessionobj[cookie.parse(socket.handshake.headers.cookie)['connect.sid']] = true;
    });

    socket.on('disconnect', function(data){
        //any cleanup actions you may want
    });

});

Ответ 2

Крис, я не смогу ответить, потому что я не эксперт в socket.io, но я могу попытаться указать вам в другом направлении, которое может вам помочь, - и уберите время разработки.

Но во-первых, отказ от ответственности: я работаю в Realtime.co и не пытаюсь делать какую-либо рекламу. Я тесно сотрудничаю с разработчиками, и я просто пытаюсь помочь вам, предоставив вам готовое решение для вашей проблемы. Кроме того, будучи игроком, я не могу держаться подальше от попыток помочь людям получить свои игры там!

В режиме реального времени используется уровень проверки подлинности/авторизации, в котором вы можете предоставить права на чтение/запись пользователей для каналов. Когда пользователи входят на веб-сайт, вы можете предоставить им права на чтение только для игрового канала, и после их входа в систему вы можете дать им права на запись. Это можно легко сделать, выполнив проверку подлинности и повторно подключившись к серверу (все это может быть сделано на стороне клиента). Однако я бы сделал это на стороне сервера, чтобы повысить безопасность.

В Realtime есть API Node.js, поэтому вы можете легко интегрировать его с вашим сервером. Поскольку у него также есть API для многих других платформ (в том числе мобильных), и все они работают одинаково, вы можете фактически использовать свою игру на нескольких платформах на одном и том же уровне связи, имея полный контроль над каналами.

Спасибо за чтение.

Edit:

Вы можете прочитать здесь документацию для получения дополнительной информации: http://docs.xrtml.org/