PHP Websocket authentifiziert Benutzer in einem Test (Pass Session Cookie)

Ich versuche ein Szenario zu testen, bei dem zum einen anonyme Benutzer sofort die Verbindung zu einer Websocket-Verbindung trennen und zum anderen authentifizierte Benutzer in der Websocket-Verbindung bleiben sollten. Der erste Fall ist mit dem Code down under einfach zu testen. Der Authentifizierungsprozess funktioniert nicht.

Zum Speichern von Sitzungen verwende ich die Cookie-Authentifizierung in Kombination mit einer Datenbank: Symfony PDO Session Storage. Alles funktioniert einwandfrei, aber wenn es darum geht, das beschriebene Verhalten mithilfe der Authentifizierung zu testen, kann ich den Benutzer in einem Test nicht authentifizieren. Als Kunde benutze ichPawl asynchroner Websocket-Client. Das sieht so aus:

\Ratchet\Client\connect('ws://127.0.0.1:8080')->then(function($conn) {
    $conn->on('message', function($msg) use ($conn) {
        echo "Received: {$msg}\n";
    });

    $conn->send('Hello World!');
}, function ($e) {
    echo "Could not connect: {$e->getMessage()}\n";
});

Ich weiß, dass ich als dritten Parameter Header-Informationen an die "connect" -Methode übergeben kann, aber ich kann keinen Weg finden, damit der Client verbunden ist und das Cookie während des ws-Handshakes korrekt übergeben wird. Ich dachte an etwas wie:

Authentifizieren Sie einen Client, indem Sie ein @ erstellauthentication tokenIch erstelle einen neuen Eintrag in der Sitzungstabelle in der Datenbank mit dem serialisierten BenutzerIch übergebe das erstellte Cookie als drittes Argument an die connect-Methode

Dies ist die Theorie, von der ich dachte, dass sie funktionieren würde, aber der Benutzer bleibt auf der Websocket-Seite immer anonym. Hier der Code zur bisherigen Theorie:

// ...
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class WebsocketTest extends WebTestCase
{

    static $closed;

    protected function setUp()
    {
      self::$closed = null;
    }


    public function testWebsocketConnection()
    {
      $loop = Factory::create();
      $connector = new Connector($loop);

      // This user exists in database user tbl
      $symfClient = $this->createSession("[email protected]");

      $connector('ws://127.0.0.1:80', [], ['Origin' => 'http://127.0.0.1', 'Cookie' => 
                 $symfClient->getContainer()->get('session')->getName() . '=' 
                . $symfClient->getContainer()->get('session')->getId()])
        ->then(function(WebSocket $conn) use($loop){

            $conn->on('close', function($code = null, $reason = null) use($loop) {
                self::$closed = true;
                $loop->stop();
            });
            self::$closed = false;

        }, function(\Exception $e) use ($loop) {
            $this->fail("Websocket connection failed");
            $loop->stop();
        });

      $loop->run();

      // Check, that user stayed logged
      $this->assertFalse(self::$closed);
    }

    private function createSession($email)
    {
      $client = static::createClient();
      $container = $client->getContainer();

      $session = $container->get('session');
      $session->set('logged', true);

      $userManager = $container->get('fos_user.user_manager');
      $em = $container->get('doctrine.orm.entity_manager');
      $loginManager = $container->get('fos_user.security.login_manager');
      $firewallName = 'main';

      $user = $userManager->findUserByEmail($email);

      $loginManager->loginUser($firewallName, $user);

      // save the login token into the session and put it in a cookie
      $container->get('session')->set('_security_' . $firewallName,
        serialize($container->get('security.token_storage')->getToken()));
      $container->get('session')->save();
      $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));


      // Create session in database
      $pdo = new PDOSessionStorage();
      $pdo->setSessId($session->getId());
      $pdo->setSessTime(time());
      $pdo->setSessData(serialize($container->get('security.token_storage')->getToken()));
      $pdo->setSessLifetime(1440);

      $em->persist($pdo);
      $em->flush();

      return $client;
  }

}

ls config_test.yml habe ich die Sitzung folgendermaßen konfiguriert:

session:
    storage_id:     session.storage.mock_file
    handler_id:     session.handler.pdo

Für die serverseitige Web-Socket-Implementierung verwende ich Ratchet, das vom folgenden Symfony-Bundle umschlossen wird:Gos Websocket Bundle

Wie authentifiziere ich den Benutzer beim Testen von Websockets? Auf dem Websocket-Server ist der Benutzer immer so etwas wie "anon-15468850625756b3b424c94871115670", aber wenn ich manuell teste, wird er korrekt verbunden.

Zusätzliche Frage (sekundär): Wie teste ich das Abonnement für Themen? (pubsub) Es gibt keine Blog-Einträge oder etwas anderes im Internet.

Update: Hat noch niemand seine Websockets auf Funktion getestet? Ist das unwichtig, nutzlos oder warum kann niemand bei diesem wichtigen Thema helfen?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage