Symfony Websockets:已记录的用户始终在主题中返回匿名

时间:2015-09-30 17:31:40

标签: php symfony cookies websocket ratchet

  

我终于找到了问题 - 但无法解释清楚。 Web服务器和Websocket服务器分别在“127.0.0.1:xyz”上运行。当我使用“127.0.0.1:xy/app_dev.php/account”访问我的网站时,一切正常,cookie被发送,读取,登录用户由clientManipulator返回。

     

当我使用“localhost:xy / app_dev.php / account”访问我的网站时,我总是找回一位匿名用户并且不会发送cookie。有人可以向我解释一下 - 这也会影响生产模式吗? (例如,用户也可以使用网站的IP连接 - 然后这会给我带来同样的问题,不是吗?)

此问题与this one有关。 (Symfony 2.7)

我已经实现了Gos Websocket Bundle,现在可以将消息实时发送到用户可以订阅的频道。目前的问题是,我无法访问我的Notification Topic类中当前登录的用户。我已经尝试过在我链接到的相关帖子中订阅的所有内容。

目前,我正在将“@ security.token_storage”注入我的主题 - 但正如我所说,其他方法的行为也是一样的。我认为这是一个“cookie /域”问题,cookie不会发送到websocket服务器。这是我的配置:

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
services.yml中的

@ session.handler.pdo:

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}]

框架会话配置为使用pdo处理程序:

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

使用websocket连接客户端的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;
}

我错过了什么?

问候。

2 个答案:

答案 0 :(得分:3)

现在很清楚,解释在于HTTP Cookie限制。在此处查找更多详细信息:http://www.cookiecentral.com/faq/#4.3

"检索cookie的主要限制是您只能检索对您的脚本所在文档有效的Cookie。也就是说,www.myserver.com上的脚本无法从www.yourserver读取Cookie 。.COM"

另外,我建议您确保在" localhost"上运行您的websocket服务器。使用" localhost"访问您网站的域名。这样做,两个域仍然是一致的。

作为一个问题,我从来没有检查过是否通过其地址(127.0.0.1)访问网站并且运行了websocket服务器" localhost"触发同样的问题。无论如何,为了回答你,不,只要你拥有正确的域名(不是ip),就不应该在prod中重现一次。

但是,Thomas的答案不对,你不能在同一个端口上运行两个服务器,因为它是端口的定义(一个端口,一个服务/进程):https://en.wikipedia.org/wiki/Port_%28computer_networking%29

答案 1 :(得分:1)

为了在web应用程序和websocket之间共享会话,两者必须在同一个域和相同的端口上运行,否则cookie将不会被浏览器发送

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

并且必须为域exemple.com(没有任何子域)配置cookie

当您的网络服务器在端口8000上运行时,似乎您的配置已设置为websocket的端口8081

希望这有帮助