Как организовать взаимодействие sock.js и express?

Добрый день.
Давно хотел познакомиться с возможностями Web Socket. Собственно для этого и было решено написать простой чат. В качестве фреймворка используется express, в качестве библиотеки для Web Socket - sock.js. И получается вот такой код:
var YAML = require('yamljs');

var conf = YAML.load('config.yml');
var conf = conf['express'];

var express = require('express')
  , routes = require('./routes')
  , start = require('./routes/start')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path')
  , sockjs = require('sockjs')

var app = express();

app.configure(function(){
	app.set('port', process.env.PORT || 3000);
	app.set('views', __dirname + conf['view']['dir']);
	app.set('view engine', conf['view']['engine']);
	app.use(express.favicon());
	app.use(express.logger(conf['logger']['name']));
	app.use(express.bodyParser());
	app.use(express.cookieParser());
	app.use(express.session({
		cookie: conf['session']['cookie'],
		secret: conf['session']['secret']
	}));
	app.use(express.methodOverride());
	app.use(app.router);
	app.use(express.static(path.join(__dirname, 'public')));
});

app.get('/', routes.index); // Главная страница. Содержит форму для ввода имени пользователя
app.get('/users', user.add); // Содержит обработчик для формы на главной странице.
app.get('/start', start.start); // Страница на которой размещается чат

var server = http.createServer(app);
var echo = sockjs.createServer();
var connList = new Array();

echo.on('connection', function (conn) {
	connList.push({connaction: conn})
	conn.on('data', function (message) {
		connList.forEach(function (thisConnaction){
			thisConnaction.write(message);
		});
	});
	conn.on('close', function () { });
});

echo.installHandlers(server, {prefix:'/echo'});

server.listen(app.get('port'), function(){
	console.log("Express server listening on port " + app.get('port'));
});


Код не сильно отличается от примеров. Как видно на сайте 3 страницы:
'/' - Главная страница. На ней размещена форма для ввода пользователем своего имени.
'/users' - Обрабатывает данные формы. В случае если имя занято перенаправляет обратно на главную или сохраняет в сессии имя пользователя и перенаправляет на '/start'.
'/start' - Собственно страница с чатом.

И вот тут у меня возникла проблема. Получить данные сессии (в данном примере имя пользователя) в обработчике Web Socket подключений у меня просто не получается.
  • Вопрос задан
  • 4561 просмотр
Решения вопроса 1
@Kilai Автор вопроса
Более подробное перечитывание документации дало свои результаты. Создатели SockJS заблокировали авторизацию через кукиз. Мотивировали это возникновением проблем безопасности если используется эмуляция через iframe.

Authorisation

SockJS-node does not expose cookies to the application. This is done deliberately as using cookie-based authorisation with SockJS simply doesn't make sense and will lead to security issues.

Cookies are a contract between a browser and an http server, and are identified by a domain name. If a browser has a cookie set for particular domain, it will pass it as a part of all http requests to the host. But to get various transports working, SockJS uses a middleman

an iframe hosted from target SockJS domain. That means the server will receive requests from the iframe, and not from the real domain. The domain of an iframe is the same as the SockJS domain. The problem is that any website can embed the iframe and communicate with it - and request establishing SockJS connection. Using cookies for authorisation in this scenario will result in granting full access to SockJS communication with your website from any website. This is a classic CSRF attack.

Basically - cookies are not suited for SockJS model. If you want to authorise a session - provide a unique token on a page, send it as a first thing over SockJS connection and validate it on the server side. In essence, this is how cookies work.

Ссылка на оригинал
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@Kilai Автор вопроса
Предполагается что есть два пути.
Первый устанавливать в cookies страницы несколько ключей, которые после установления соединения будут отправлены по Web Socket. И по ним из переменной app будет выужена нужная информация.
Второй если это возможно при установлении соединения пока клиент и сервер ещё общаются через HTTP переслать идентификатор сессии.

Интересно как это реализовать если возможно.
Ответ написан
Комментировать
pomeo
@pomeo
А причём здесь websocket, вы пишете что на / у вас форма, и передаёте вы её на /users и дальше хотите в сессии увидеть имя пользователя. Вам req.session надо, а не вебсокеты.
Ответ написан
@Kilai Автор вопроса
@pomeo команда

echo.installHandlers(server, {prefix:'/echo'});

вешает обработчик на путь '/echo' явно не затрагивая express. А следовательно, ни какая переменная req, не доступна в обработчике нового Web Socket подключения

echo.on('connection', function (conn) {
    connList.push({connaction: conn})
    conn.on('data', function (message) {
        connList.forEach(function (thisConnaction){
            thisConnaction.write(message);
        });
    });
    conn.on('close', function () { });
});
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы