socket.io аутентификация после установки сокета - PullRequest
14 голосов
/ 06 января 2012

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

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

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

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

РЕДАКТИРОВАТЬ

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

client.on('onLogin', loginfunction);

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

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

Cheers

Ответы [ 2 ]

6 голосов
/ 17 января 2013

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

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

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

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

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

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

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

Теперь при получении нового 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 голосов
/ 16 января 2013

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

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

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

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

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

Edit:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...