5

I found a post on Laravel.io on how to load Laravel sessions into Ratchet which is outdated and uses Laravel 5.4 so I've altered a few things to get this to work with Laravel 8.x

public function onOpen(ConnectionInterface $conn)
{
    // Attach connection
    $this->clients->attach($conn);

    // Create a new session handler for this client
    $session = (new SessionManager(App::getInstance()))->driver();

    // Get the cookies
    $cookiesRaw = $conn->httpRequest->getHeader('Cookie');
    $cookies = [];

    if(count($cookiesRaw)) {
        $cookies = Header::parse($cookiesRaw)[0]; // Array of cookies
    }

    // Get the laravel's one - todo: try catch
    $sessionId = Crypt::decrypt(urldecode($cookies[Config::get('session.cookie')]), false);

    var_dump($sessionId);

    // Set the session id to the session handler
    $session->setId($sessionId);

    // Bind the session handler to the client connection
    $conn->session = $session;

    var_dump($conn->session->getId());
}

I then altered the send message too because I am receiving unexpected results.

public function onMessage(ConnectionInterface $conn, MessageInterface $msg)
{
    $conn->session->start();
    $sessionId = $conn->session->getId();

    var_dump($sessionId);

    if(!is_null(($decoded = json_decode(base64_decode($msg), true))) && array_diff(['message'], array_keys($decoded)))
        return;

    var_dump($decoded['message']);

    return;
}

I test this with JS front-end like so:

class WebRTC
{
    socket;
    constants;
    timerId;

    constructor(protocol, fqdns, port) {
        this.constants = {
            protocol: protocol,
            fqdns: fqdns,
            port: port
        };

        this.listenChanges();
    }

    listenChanges() {
        this.socket = new WebSocket(`${this.constants.protocol}://${this.constants.fqdns}:${this.constants.port}`);

        this.socket.onmessage = e => {
            console.log(atob(e.data));
        };

        this.socket.onerror = () => {
            this.socket.close();
        };

        this.socket.onopen = () => {
            console.info('Connected to WebRTC Chat Server...');

            this.socket.send(btoa(JSON.stringify({
                message: '{{ session()->getId() }}' // Expected session
            })));

            clearInterval(this.timerId);

            this.socket.onclose = () => {
                this.timerId = setInterval(() => {
                    this.listenChanges();
                }, 1000);
            };
        };
    }
}

new WebRTC('ws', '127.0.0.1', '8080');

& When the connection opens, I sent the session()->getId() which is the expected session I need. However, my output in the CLI is:

onOpen() : $sessionId

string(81) "b0e41cf0d856bdfc8427e1fdde62d5a154519f9c|MLXa9H2BbnQmySt2hRB360UANxLGHyz6iRMxGcoG"

onOpen() : $conn->session->getId()

string(40) "qyaDOQjNFlbrbjvvKRE1m5sN0dsGqqAsoMfkeqyU"

onMessage(): $conn->session->getId()

string(40) "qyaDOQjNFlbrbjvvKRE1m5sN0dsGqqAsoMfkeqyU"

JS blade formatted actual session that is sent as a message

string(40) "MLXa9H2BbnQmySt2hRB360UANxLGHyz6iRMxGcoG"

Here, my expected onMessage() method receive the dependency injected $conn (ConnectionInterface) with the ->session->getId() of the actual session()->getId() so I can make Auth::user() work.

Any ideas on what I'm doing wrong? I tried the var_dump($conn->session->get(Auth::getName())); as the Laravel.Io says to do but it returns null on the var_dump and my user is logged in.

This should then give me access to use User::find() or Auth::user().

Jaquarh
  • 6,493
  • 7
  • 34
  • 86
  • Is your Javascript code inside a Blade template, or just a plain JS? Because the format [{{ }}](https://laravel.com/docs/8.x/blade#introduction) is used only within Blade templates and must be processed by PHP interpreter before output. – Daniel Protopopov Mar 30 '21 at 12:43
  • It is inside a blade file, I’m just sending my expected session ID to my Server so I can verify the data is the same - but as you can see, it doesn’t match. Theres no issue with the JS. In this case, the formatted blade output gives me MLXa9H2BbnQmySt2hRB360UANxLGHyz6iRMxGcoG as seen in the CLI response @Daniel Protopopov – Jaquarh Mar 30 '21 at 18:09
  • If you require to authenticate user, see [here](https://stackoverflow.com/questions/34762684/laravel-ratchet-socket-auth), as there's no need to go this route with saving cookie directly in the client' code. – Daniel Protopopov Mar 30 '21 at 19:45
  • There is no difference here, its a Laravel 5.4 solution and the Laravel-Ratchet package no longer exists. The same question links to the Laravel.io link I have linked in the OP. I’ve already altered this to match with Laravel 8 but it seems it does not work the same as it used to thus why I’m now asking an extended question from the previous 5.4 solution. The Auth facade returns null with Auth::user() and rightfully so because its connection is through Ratchet and not Laravel within the Web Socket transactions. @Daniel Protopopov – Jaquarh Mar 30 '21 at 20:08
  • Also, the session ID is sent in the Web socket message for me to verify the actual expected session with the back-end session I receive after the cookie is decrypted and stored within Ratchet. It is debug, it would not co-exist or be sent within a request. You’re confused @Daniel Protopopov – Jaquarh Mar 30 '21 at 20:15

0 Answers0