Хорошо, Грег был достаточно любезен, чтобы предоставить полный пример реализации клиента, так что я больше ничего не буду делать по этому поводу. Он работает с несколькими настройками и модификациями практически для любого варианта использования, который я могу придумать. Я отмечу его ответ как правильный. Но его вклад касался только теории реализации серверной части, поэтому я попытаюсь заполнить пробелы здесь для постчетности.
Однако я должен указать, что решение здесь не является полным, поскольку оно не дает мне общего сеанса между моим соединением SPA/REST и моим соединением WS.
Я обнаружил, что запрос аутентификации, передаваемый автобаном, на самом деле является вариантом RPC и по какой-то причине имеет жестко закодированные названия тем, любопытно напоминающие обычные URL-адреса:
- 'http://api.wamp.ws/procedure#authreq' - for auth requests
- 'http://api.wamp.ws/procedure#auth' - for signed auth client responses
Мне нужно было создать еще два маршрута в моем Laravel route.php
// WS CRA routes
Latchet::topic('http://api.wamp.ws/procedure#authreq', 'app\\socket\\AuthReqController');
Latchet::topic('http://api.wamp.ws/procedure#auth', 'app\\socket\\AuthReqController');
Теперь у контроллера Latchet есть 4 метода: subscribe
, publish
, call
и unsubscribe
. Поскольку и вызовы authreq, и вызовы auth, сделанные автобаном, являются вызовами RPC, они обрабатываются методом call
на контроллере.
Решение, впервые предложенное oberstet, а затем поддержанное Грегом, описывает временный ключ аутентификации и секрет, генерируемые по запросу и удерживаемые временно ровно столько времени, сколько требуется для проверки процедурой WS CRA. Поэтому я создал конечную точку REST, которая генерирует постоянную пару значений ключа. Конечная точка здесь не указана, так как я уверен, что это тривиально.
class AuthReqController extends BaseTopic {
public function subscribe ($connection, $topic) { }
public function publish ($connection, $topic, $message, array $exclude, array $eligible) { }
public function unsubscribe ($connection, $topic) { }
public function call ($connection, $id, $topic, array $params) {
switch ($topic) {
case 'http://api.wamp.ws/procedure#authreq':
return $this->getAuthenticationRequest($connection, $id, $topic, $params);
case 'http://api.wamp.ws/procedure#auth':
return $this->processAuthSignature($connection, $id, $topic, $params);
}
}
/**
* Process the authentication request
*/
private function getAuthenticationRequest ($connection, $id, $topic, $params) {
$auth_key = $params[0]; // A generated temporary auth key
$tmpUser = $this->getTempUser($auth_key); // Get the key value pair as persisted from the temporary store.
if ($tmpUser) {
$info = [
'authkey' => $tmpUser->username,
'secret' => $tmpUser->secret,
'timestamp' => time()
];
$connection->callResult($id, $info);
} else {
$connection->callError($id, $topic, array('User not found'));
}
return true;
}
/**
* Process the final step in the authentication
*/
private function processAuthSignature ($connection, $id, $topic, $params) {
// This should do something smart to validate this response.
// The session should be ours right now. So store the Auth::user()
$connection->user = Auth::user(); // A null object is stored.
$connection->callResult($id, array('msg' => 'connected'));
}
private function getTempUser($auth_key) {
return TempAuth::findOrFail($auth_key);
}
}
Теперь где-то здесь я ошибся. Потому что, если бы я должен был унаследовать сеанс ajax, который держит мое приложение, я мог бы вызывать Auth::user() из любого из моих других контроллеров на основе WS Latchet и автоматически отображать текущего пользователя, вошедшего в систему. Но это не так. Так что, если кто-то увидит, что я делаю неправильно, дайте мне крик. Пожалуйста!
Поскольку я не могу получить общий сеанс, я в настоящее время обманываю, передавая настоящее имя пользователя как вызов RPC вместо выполнения полного CRA.
person
Øystein Amundsen
schedule
24.06.2014