Symfony Websockets: Logged User always returns anonym within Topic

此生再无相见时 提交于 2019-12-23 17:21:14

问题


I finally found the problem - but can't explain it well. The Webserver and Websocket Server are running on "127.0.0.1:xyz" each. When I access my website with "127.0.0.1:xy/app_dev.php/account" , everything is working, cookies are sent, read and the logged in user is given back by the clientManipulator.

When I access my website with "localhost:xy/app_dev.php/account", I always get back an anonymous user and the cookies are not sent. Can someone explain this to me please - and will this have affects in production mode too ? (e.g. a user can also connect with the IP of the website - and then this would bring me to the same problem, wouldn't it ? )

This question is related to this one. (Symfony 2.7)

I have implemented the Gos Websocket Bundle and can now send messages in realtime to channels, where users can subscribe to. The problem currently is, that I don't have access to the currently logged in User within my Notification Topic class. I already tried all that was subscribed in the related post I linked to.

Currently, I am injecting the "@security.token_storage" into my topic - but as I said the behaviour is the same for the other approaches too. I think this is a "cookie / domain" problem, the cookies are not sent to the websocket server. Here is my configuration:

Symfony / php Webserver: "Server running on 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 in 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 session configured to use pdo handler:

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

JavaScript part to connect client with websocket:

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);
    });

});

This is my configuration, the token storage gets injected in a service for the Notification Topic. The "onSubscribe" method of the topic gets hit, but the user stays anonymous, even if I am logged in:

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

What did I miss ?

Regards.


回答1:


As this is now clear, the explanation resides in HTTP cookies limitations. Find more details here: http://www.cookiecentral.com/faq/#4.3

"The main limit on retrieving a cookie is that you can only retrieve cookies that are valid for the document your script resides in. That is, a script on www.myserver.com cannot read cookies from www.yourserver.com."

Also, I suggest you ensure running your websocket server on the "localhost" domain to access your website using "localhost". Doing so, both domains will still be in accordance.

As a question to myself, I have never checked if accessing the website by its address (127.0.0.1) and having the websocket server running on "localhost" trigger the same issue. Anyway, to answer you, no, this should not reproduce once in prod, as soon as you have the right domain (not ip).

However, the answer from Thomas is not right, you cannot run both servers on the same port, as it is the definition for ports (one port, one service/process): https://en.wikipedia.org/wiki/Port_%28computer_networking%29 .




回答2:


In order to share session between web app and websocket, both must be running on the same domain and the same port, otherwise the cookie will not be sent by the browser

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

and the cookie must be configured for domain exemple.com (without any subdomain)

It seems that your config is setup for port 8081 for the websocket when your webserver is running on port 8000

Hope this helps



来源:https://stackoverflow.com/questions/32872331/symfony-websockets-logged-user-always-returns-anonym-within-topic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!