GeniusesOfSymfony / WebSocketBundle

:part_alternation_mark: Websocket server for Symfony applications (powered by Ratchet), includes a Autobahn.JS based JavaScript client
MIT License
608 stars 140 forks source link

PDO Session doesn't detect log in user #305

Open navalex opened 6 years ago

navalex commented 6 years ago

Hi,

I have setup a basic PDO Session system to get user information for my websocket chat. The sessions are working cause Symfony create new sessions in my database. But i don't know why, the bundle always detect anonymous user, even if i'm logged in.

I founded no solution for this problem, so if someone can help me. :)

gos configuration:

gos_web_socket:
    server:
        port: 8080
        host: 127.0.0.1
        router:
            resources:
                - '@CoreBundle/Resources/config/pubsub/routing.yml'
    client:
        firewall: main
        session_handler: session.handler.pdo

services:

pdo:
        class: PDO
        arguments:
            - 'mysql:host=%database_host%;dbname=%database_name%'
            - '%database_user%'
            - '%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}]

my topic:

core.topic_sample_service:
        class: CoreBundle\Topic\ChatTopic
        arguments: [ "@gos_web_socket.websocket.client_manipulator"]
        tags:
            - { name: gos_web_socket.topic }
i-telligence-af commented 6 years ago

How are you setting up the ws connection on the client side?

Can you post your security.yml?

ma-gu-16 commented 5 years ago

exaclty same config and same prob here.

session after frontend user login succesfull saved in database.

but websocket debug:

12:26:21 INFO [websocket] Starting web socket 12:26:21 INFO [websocket] Launching Ratchet on 127.0.0.1:8942 PID: 1234 12:26:21 DEBUG [websocket] INSERT CLIENT 2468 ["user" => "s:36:"anon-5395846205c52db5da4b81427641409";"] 12:26:21 INFO [websocket] anon-5395846205c52db5da4b81427641409 connected ["connection_id" => 2468,"session_id" => "5395846205c52db5da4b81427641409","storage_id" => 2468]

i thougth it should be the user object. if i debug onSubscribe function: $user = $this->clientManipulator->getClient($connection); var_dump($user);

Result: string(36) "anon-5395846205c52db5da4b81427641409"

whats wrong?

ma-gu-16 commented 3 years ago

its still an issue. maybe someone has an solution ?

mbabker commented 3 years ago

The config looks fine.

For the session bit to work correctly, it needs to be able to parse the session cookie from the main website. If your websocket subdomain is different from your website subdomain (i.e. for one of my clients we have ws.example.com for the websocket connections and www.example.com for the main site), then the session cookie needs to be configured to allow all subdomains:

framework:
    session:
        cookie_domain: '.example.com'
ma-gu-16 commented 3 years ago

The config looks fine.

For the session bit to work correctly, it needs to be able to parse the session cookie from the main website. If your websocket subdomain is different from your website subdomain (i.e. for one of my clients we have ws.example.com for the websocket connections and www.example.com for the main site), then the session cookie needs to be configured to allow all subdomains:

framework:
    session:
        cookie_domain: '.example.com'

yes this is set.

webapp runs at: https:/portal.domain.local and websocket runs at: ws://127.0.0.1:1337

ma-gu-16 commented 3 years ago

services

  Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
    arguments:
      - '%env(DATABASE_URL)%'
      - { db_table: 'symfony_user_session', db_id_col: 'guid' }

framework


  session:
    handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
    gc_maxlifetime: 36000
    cookie_secure: false
    cookie_samesite: null
    cookie_domain: '.local'
    name: SFSESSID

gos

gos_web_socket:
  client:
    session_handler: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
    firewall: main
ma-gu-16 commented 3 years ago

i have debugged the headers.... i seems the rachet or gos doesnt take the pdo handler....


GuzzleHttp\Psr7\Request {#6082
  -method: "GET"
  -requestTarget: null
  -uri: GuzzleHttp\Psr7\Uri {#6201
    -scheme: "http"
    -userInfo: ""
    -host: "127.0.0.1"
    -port: 8080
    -path: "/"
    -query: ""
    -fragment: ""
  }
  -headers: array:13 [
    "Host" => array:1 [
      0 => "127.0.0.1:8080"
    ]
    "Connection" => array:1 [
      0 => "Upgrade"
    ]
    "Pragma" => array:1 [
      0 => "no-cache"
    ]
    "Cache-Control" => array:1 [
      0 => "no-cache"
    ]
    "User-Agent" => array:1 [
      0 => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
    ]
    "Upgrade" => array:1 [
      0 => "websocket"
    ]
    "Origin" => array:1 [
      0 => "https://portal.domain.local"
    ]
    "Sec-WebSocket-Version" => array:1 [
      0 => "13"
    ]
    "Accept-Encoding" => array:1 [
      0 => "gzip, deflate, br"
    ]
    "Accept-Language" => array:1 [
      0 => "de,de-DE;q=0.9"
    ]
    "Sec-WebSocket-Key" => array:1 [
      0 => "HuJT+YuHfff47c17QFDg=="
    ]
    "Sec-WebSocket-Extensions" => array:1 [
      0 => "permessage-deflate; client_max_window_bits"
    ]
    "Sec-WebSocket-Protocol" => array:1 [
      0 => "wamp"
    ]
  ]
  -headerNames: array:13 [
    "host" => "Host"
    "connection" => "Connection"
    "pragma" => "Pragma"
    "cache-control" => "Cache-Control"
    "user-agent" => "User-Agent"
    "upgrade" => "Upgrade"
    "origin" => "Origin"
    "sec-websocket-version" => "Sec-WebSocket-Version"
    "accept-encoding" => "Accept-Encoding"
    "accept-language" => "Accept-Language"
    "sec-websocket-key" => "Sec-WebSocket-Key"
    "sec-websocket-extensions" => "Sec-WebSocket-Extensions"
    "sec-websocket-protocol" => "Sec-WebSocket-Protocol"
  ]
  -protocol: "1.1"
  -stream: null
}

vendor\cboden\ratchet\src\Ratchet\Session\SessionProvider.php

seems like at line 76 the id is empty. there are no Cookie Headers. in my debug. but if i check it with google toolbar there are the Cookie headers @client side. and its the correct sess_id like the one in the database.

\vendor\cboden\ratchet\src\Ratchet\Session\Storage\VirtualSessionStorage.php

if i copy this id at line $this->saveHandler->read($this->saveHandler->getId()); it works.

but why is session_id empty?

mbabker commented 3 years ago

You’re accessing the websocket server by IP address and the website with a domain name. Effectively, the websocket server is on a separate domain and the session cookie won’t be sent when your browser makes the websocket connection.

ma-gu-16 commented 3 years ago

You’re accessing the websocket server by IP address and the website with a domain name. Effectively, the websocket server is on a separate domain and the session cookie won’t be sent when your browser makes the websocket connection.

i use the ip for the client connect too. i just followed the doumentation here. its not possible to start the server if i enter a domainname instead of ip.

mbabker commented 3 years ago

You need both the domain and the IP in the config. I’m not near a computer to check my own app configs, but essentially one of the fields is the IP address and React’s Socket package (IIRC) uses that and the port to run the server and handle connections, then there’s another field which should have the domain name in it if you’re using the Twig globals since that’s the one that is used to build the address your browser will connect to. I also noticed you’ve got HTTPS for the domain and WS for websocket, they either both need to be secure (so HTTPS and WSS) or not secure (HTTP and WS) otherwise that might cause issues as well.

I can also bounce this off my own configs later, but like I said, not near a computer at the moment.

ma-gu-16 commented 3 years ago

Ok i got it.... seems like the problem is ssl if i want ssl i need to use wss cause of cross-browser. i need an apache proxy or remove ssl , after that the config works as above.

mbabker commented 3 years ago

I haven't touched either of the wiki articles on this repo, but before we moved to our current hosting setup, we were using something pretty similar to https://github.com/GeniusesOfSymfony/WebSocketBundle/wiki/Set-up-Gos-Web-Socket-Bundle-in-AWS-(Production---Symfony-Application)-with-SSL for the proxy layer. I've never looked at the other article in there, but it may be of help to you too.

Admittedly, all my localhost stuff is plain HTTP so I don't have any of the proxy issues in development.