我試圖測試一個場景,一方面,匿名用戶應該立即從WebSocket連接斷開連接,另一方面,經過身份驗證的用戶應該停留在websocket連接。第一種情況很容易通過使用下面的代碼進行測試。身份驗證過程不起作用。PHP Websocket在測試中驗證用戶(傳遞會話cookie)
對於會話存儲,我將Cookie身份驗證與數據庫結合使用:Symfony PDO Session Storage。這一切都工作正常,但是當涉及到通過使用身份驗證來測試所描述的行爲時,我不知道如何在測試中對用戶進行身份驗證。作爲一個客戶,我使用Pawl asynchronous Websocket client.這看起來如下:
\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";
});
我知道,作爲第三個參數,我可以通過報頭信息「連接」的方法,但我不能找到一種方法,使客戶端已連接並且在ws握手期間cookie正確傳遞。我認爲是這樣的:
- 通過創建authentication token
- 我創建的會話表中的數據庫與序列化用戶
- 一個新條目我通過創建的cookie作爲第三個參數驗證客戶端連接方法
這是我認爲可以工作的理論,但用戶始終在websocket一側保持匿名。下面的代碼到理論至今:
// ...
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;
}
}
由於config_test.yml,我配置了會話方式如下:
session:
storage_id: session.storage.mock_file
handler_id: session.handler.pdo
對於服務器端的WebSocket實現,我使用的棘輪,其被由以下Symfony包裹包裝:Gos Websocket Bundle
如何在測試websockets時驗證用戶?在websocket服務器上,用戶總是像「anon-15468850625756b3b424c94871115670」,但是當我手動測試時,他的連接正確。
其他問題(二級):如何測試訂閱主題? (pubsub) 在互聯網上沒有關於此的博客條目或任何其他內容。
更新:沒有人曾經功能測試過他們的websockets?這是不重要的,無用的或爲什麼任何人都無法幫助那個重要的話題?
你只想找一種方式來傳遞cookie,或者你想立即發送一個sessionId/userId的例子嗎? – mitchken
我已經用我寫的代碼更新了這個問題。問題是,在棘輪方面,用戶在測試中保持匿名。也許我錯誤地傳遞了cookie。會話ID在cookie中傳輸。 – user3746259
''Cookie'=> $ symfClient-> getContainer() - > get('session') - > getId()。 '='。 $ symfClient-> getContainer() - > get('session') - > getId()'確定這是正確的?首先不應該是cookie的名字? – bwoebi