У меня есть рабочее приложение php, в котором я хочу добавить поддержку в режиме реального времени. Я хотел бы использовать nodejs/socket.io, чтобы добавить такую функциональность.
Первая проблема, которую я обнаружил, - это то, как правильно разрешить пользователю на стороне nodejs (пользователь уже аутентифицирован на php-сервере через сеанс PHP). Используя socket.handshake.header.cookie на стороне nodejs, я могу проанализировать и получить идентификатор сеанса PHP, с которым я могу пройти аутентификацию через redis/memcache/database (в зависимости от того, что я использовал для сохранения информации о сеансе).
Все выглядит здорово, когда пользователь открывает только одну вкладку/окно сайта - при наличии большего количества и использования session_regenerate_id(), в nodejs пользователь аутентифицируется с помощью другого ключа sessionid, поэтому я не могу различить две вкладки ничем иным, кроме идентификатора сокета, с которым они связаны. Когда пользователь выходит из системы, он не должен получать какие-либо сообщения на какой-либо вкладке (потому что он уже вышел из каждой вкладки/окна из этого браузера). Поэтому при выводе сообщения (отправленного из браузера непосредственно перед выходом из PHP файлов) я должен удалить все соединения сокетов, подключенные к авторизованному идентификатору пользователя. Но что делать, если пользователь входит в систему на двух устройствах (например, браузер pc и ipad safaris). После выхода на одно устройство он не должен получать сообщения на устройстве, которое он выходил, а не на каждом устройстве. Как я могу отличить соединения от разных устройств/браузеров в socket.io? Конечно, использование здесь session_regenerate_id() было бы эффективным, но что я могу сделать, если я действительно хочу использовать эту функцию?
Еще одна проблема, которую я имею, - это проблема безопасности (или даже вопрос). Предположим, что авторизованный пользователь в приложении может видеть страницу example.com/user1 (которая является новостной лентой для пользователя1) и не может видеть example.com/user2 (fe. He не имеет прав на это). Я хочу, чтобы socket.io отправлял сообщения об обновлениях в браузер, когда пользователь находится на example.com/user1, и, конечно же, не отправлять, когда пользователь находится на example.com/user2 сайт. На стороне socket.io я могу прочитать адрес рефератора (поэтому, предположительно, когда пользователь находится на сайте user2, он не получает никакого соединения socket.io). Возникает вопрос: следует ли сравнивать адрес реферата с правами аутентифицированного пользователя на стороне node.js? Или, может быть, значение реферера безопасно на стороне node.js? Добавление другой проверки db на стороне node.js замедлит ее работу (потому что почти каждый запрос должен иметь такую же проверку базы данных с двух сторон - PHP и node.js).
Или, может быть, вся концепция приложения socket.io + PHP, работающего так, как я представил, ошибочна?
UPDATE
Я думаю, что нашел способ опустить проблемы с первым вопросом - в основном я просто добавляю еще один cookie (кроме PHPSESSID) fe. с именем NODESESSID, который я генерирую (например, с помощью uniqid()), когда пользователь авторизован. Теперь авторизация на стороне node.js сравнивает PHPSESSID и NODESESSID (оба должны совпадать). Теперь, когда пользователь выходит из системы, он отправляет сообщение в socket.io и socket.io отключает все сокеты с помощью NODESESSID. Это похоже на использование преимуществ восстановления идентификатора сеанса и не восстановления идентификатора сеанса (но не уязвим для фиксации сеанса, не так ли?).