Symfony Websockets: зарегистрированный пользователь всегда возвращает анонимность в теме

Наконец-то я нашел проблему, но не могу ее хорошо объяснить. Веб-сервер и сервер веб-сокетов работают на «127.0.0.1: xyz» каждый. Когда я захожу на свой веб-сайт с помощью «127.0.0.1:xy/app_dev.php/account», все работает, файлы cookie отправляются, читаются, а вошедший в систему пользователь возвращается clientManipulator.

Когда я захожу на свой веб-сайт с помощью «localhost:xy/app_dev.php/account», я всегда получаю обратно анонимного пользователя, и файлы cookie не отправляются. Может кто-нибудь объяснить мне это, пожалуйста, и будет ли это влиять на производственный режим? (например, пользователь также может подключиться к IP-адресу веб-сайта - и тогда это приведет меня к той же проблеме, не так ли?)

Этот вопрос связан с этим. (Симфония 2.7)

Я внедрил Gos Websocket Bundle и теперь могу отправлять сообщения в режиме реального времени на каналы, на которые пользователи могут подписаться. В настоящее время проблема заключается в том, что у меня нет доступа к текущему пользователю, вошедшему в систему, в моем классе темы уведомлений. Я уже пробовал все, что было подписано в соответствующем посте, на который я ссылался.

В настоящее время я добавляю «@security.token_storage» в свою тему, но, как я уже сказал, поведение такое же и для других подходов. Я думаю, что это проблема с файлами cookie/доменами, файлы cookie не отправляются на сервер веб-сокетов. Вот моя конфигурация:

Веб-сервер Symfony/php: «Сервер работает на http://127.0.0.1:8000"

Gos websocket config.yml:

gos_web_socket:
  server:
    port: 8081        #The port the socket server will listen on
    host: 127.0.0.1   #The host ip to bind to
    router:
      resources:
        - @MessageBundle/Resources/config/pubsub/routing.yml
  client:
    firewall: main
    session_handler: @session.handler.pdo
  pushers:
    zmq:
        host: 127.0.0.1
        port: 5555
        persistent: true
        protocol: tcp

@session.handler.pdo в services.yml:

pdo:
      class: PDO
      arguments:
          dsn: mysql:host=%database_host%;port=%database_port%;dbname=%database_name%
          user: %database_user%
          password: %database_password%
      calls:
          - [ setAttribute, [3, 2] ] # \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION

session.handler.pdo:
      class:     Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
      arguments: [@pdo, {lock_mode: 0}]

Сеанс Framework настроен на использование обработчика pdo:

session:
  # handler_id set to null will use default session handler from php.ini
  handler_id:  session.handler.pdo

Часть JavaScript для подключения клиента к веб-сокету:

var webSocket = WS.connect("ws://127.0.0.1:8000");

webSocket.on("socket/connect", function(session){

    session.subscribe("account/notification", function(uri, payload){
        console.log("Received message", payload.msg);
    });

});

Это моя конфигурация, хранилище токенов внедряется в службу для темы уведомлений. Метод «onSubscribe» темы срабатывает, но пользователь остается анонимным, даже если я вошел в систему:

public function onSubscribe(ConnectionInterface $connection, Topic $topic, WampRequest $request)
{
    // always returns anonym
    dump($this->tokenStorage->getToken()->getUser());die;
}

Что я упустил ?

С уважением.


person user3746259    schedule 30.09.2015    source источник


Ответы (2)


Как теперь ясно, объяснение заключается в ограничениях файлов cookie HTTP. Подробнее читайте здесь: http://www.cookiecentral.com/faq/#4.3

«Основное ограничение на получение файла cookie заключается в том, что вы можете получать только те файлы cookie, которые действительны для документа, в котором находится ваш скрипт. То есть скрипт на www.myserver.com не может читать файлы cookie с www.yourserver.com».

Кроме того, я предлагаю вам убедиться, что ваш веб-сервер работает в домене «localhost», чтобы получить доступ к вашему веб-сайту с помощью «localhost». При этом оба домена по-прежнему будут соответствовать друг другу.

Как вопрос к себе, я никогда не проверял, вызывает ли доступ к веб-сайту по его адресу (127.0.0.1) и запуск сервера веб-сокетов на «localhost» ту же проблему. В любом случае, чтобы ответить вам, нет, это не должно воспроизводиться один раз в prod, как только у вас есть правильный домен (не ip).

Однако ответ Томаса неверен, вы не можете запускать оба сервера на одном и том же порту, так как это определение для портов (один порт, одна служба/процесс): https://en.wikipedia.org/wiki/Port_%28computer_networking%29 .

person wr0ng.name    schedule 01.10.2015
comment
Спасибо за ваше объяснение, я проверю его в продукте и опубликую результаты здесь, когда сделаю это. - person user3746259; 03.10.2015
comment
скорее всего, вы скопировали пример кода, где js-фрагмент ws://127.0.0.1, поэтому вставьте туда свое имя хоста. - person john Smith; 02.11.2016

Чтобы разделить сеанс между веб-приложением и веб-сокетом, оба должны работать в одном домене и на одном и том же порту, иначе браузер не отправит файл cookie.

Web app: http://www.exemple.com:80
Websocket: ws://ws.exemple.com:80

и файл cookie должен быть настроен для домена example.com (без субдомена)

Кажется, что ваша конфигурация настроена на порт 8081 для веб-сокета, когда ваш веб-сервер работает на порту 8000.

Надеюсь это поможет

person Thomas Klein    schedule 01.10.2015
comment
Как они оба могут работать на одном порту? Как говорится в документации по храповику, требуется только тот же домен. Вы читали мою коробку выше в начале моего поста? - person user3746259; 01.10.2015
comment
Я заметил это в документации храповика, но вот сообщение от разработчика храповика с другим мнением: groups.google.com/d/msg/ratchet-php/_IasVwmnATQ/_qSZredEyJcJ - person Thomas Klein; 01.10.2015
comment
Хм, это неправда. К тому же я выше писал, что работает (с разными портами), просто возник вопрос про localhost/127.0.0.1 - person user3746259; 01.10.2015