Php Laravel,WebSockets-验证服务器上的用户
我目前遇到了使用Laravel和RachetPHP在服务器上处理用户身份验证的问题 到目前为止,我尝试的是:Php Laravel,WebSockets-验证服务器上的用户,php,session,laravel,eloquent,ratchet,Php,Session,Laravel,Eloquent,Ratchet,我目前遇到了使用Laravel和RachetPHP在服务器上处理用户身份验证的问题 到目前为止,我尝试的是: 我将会话的驱动程序类型更改为数据库,给了我一个id和有效负载列。使用\Session::getId()返回一个40个字符的字符串。 WebSocket连接发送的cookie信息确实包含XSRF-TOKEN和laravel_会话,两者都包含>200个字符串。用户会话的数据库ID与\session::getId()返回的ID不同 我已经通过websocket消息发送了当前的CSRF令牌,但
- 我将会话的驱动程序类型更改为数据库,给了我一个id和有效负载列。使用
返回一个40个字符的字符串。 WebSocket连接发送的cookie信息确实包含XSRF-TOKEN和laravel_会话,两者都包含>200个字符串。用户会话的数据库ID与\Session::getId()
返回的ID不同\session::getId()
- 我已经通过websocket消息发送了当前的CSRF令牌,但是我不知道如何验证它(内置的验证器使用请求-我在websocket服务器范围内没有)
- 验证用户的东西(ID或令牌)
- 评论本身
- 在服务器上进行身份验证
- 访问他的角色,从而对他的角色执行基本CRUD操作
- 如果用户经过身份验证(csrf令牌?)
- 如果用户是角色的所有者(用另一个用户的角色id欺骗请求非常简单)
如果您需要更多信息,请告诉我。我想我找到了解决方案。虽然不是很干净,但它做了它应该做的事情(我猜…) WebSocket服务器由Artisan命令()启动。我将这些类注入命令:
light\Contracts\Encryption\Encrypter
-一个定制的CsrfTokenVerifier,它只比较两个字符串(将在其中放入更多的后续逻辑代码)App\Contracts\CsrfTokenVerifier
onMessage
方法中,我解析发送的消息,其中包含:
- 用户的CSRF令牌
- 用户的字符id
public function onMessage(ConnectionInterface $from, NetworkMessage $message) {
if (!$this->verifyCsrfToken($from, $message)) {
throw new TokenMismatchException;
}
if (!$this->verifyUser($from, $message)) {
throw new \Exception('test');
}
...
}
private function verifyUser(ConnectionInterface $conn, NetworkMessage $message) {
$cookies = $conn->WebSocket->request->getCookies();
$laravel_session = rawurldecode($cookies['laravel_session']);
$id = $this->encrypter->decrypt($laravel_session);
$session = Session::find($id);
$payload = unserialize(base64_decode($session->payload));
$user_id = $payload['user_id'];
$user = User::find($user_id);
$characters = $this->characterService->allFrom($user);
$character_id = $message->getHeader()['character_id'];
return $characters->contains($character_id);
}
private function verifyCsrfToken($from, NetworkMessage $message) {
$header = $this->getHeaderToken($from);
return $this->verifier->tokensMatch($header, $message->getId());
}
代码肯定会更干净,但作为一个快速的黑客,它是有效的。我认为,与其使用会话模型,不如使用Laravel
DatabaseSessionHandler
我想我找到了一个解决方案。虽然不是很干净,但它做了它应该做的事情(我猜…)
WebSocket服务器由Artisan命令()启动。我将这些类注入命令:
light\Contracts\Encryption\Encrypter
-一个定制的CsrfTokenVerifier,它只比较两个字符串(将在其中放入更多的后续逻辑代码)App\Contracts\CsrfTokenVerifier
onMessage
方法中,我解析发送的消息,其中包含:
- 用户的CSRF令牌
- 用户的字符id
public function onMessage(ConnectionInterface $from, NetworkMessage $message) {
if (!$this->verifyCsrfToken($from, $message)) {
throw new TokenMismatchException;
}
if (!$this->verifyUser($from, $message)) {
throw new \Exception('test');
}
...
}
private function verifyUser(ConnectionInterface $conn, NetworkMessage $message) {
$cookies = $conn->WebSocket->request->getCookies();
$laravel_session = rawurldecode($cookies['laravel_session']);
$id = $this->encrypter->decrypt($laravel_session);
$session = Session::find($id);
$payload = unserialize(base64_decode($session->payload));
$user_id = $payload['user_id'];
$user = User::find($user_id);
$characters = $this->characterService->allFrom($user);
$character_id = $message->getHeader()['character_id'];
return $characters->contains($character_id);
}
private function verifyCsrfToken($from, NetworkMessage $message) {
$header = $this->getHeaderToken($from);
return $this->verifier->tokensMatch($header, $message->getId());
}
代码肯定会更干净,但作为一个快速的黑客,它是有效的。我认为,与其使用会话模型,不如使用Laravel
DatabaseSessionHandler
我想我找到了一个解决方案。虽然不是很干净,但它做了它应该做的事情(我猜…)
WebSocket服务器由Artisan命令()启动。我将这些类注入命令:
light\Contracts\Encryption\Encrypter
-一个定制的CsrfTokenVerifier,它只比较两个字符串(将在其中放入更多的后续逻辑代码)App\Contracts\CsrfTokenVerifier
onMessage
方法中,我解析发送的消息,其中包含:
- 用户的CSRF令牌
- 用户的字符id
public function onMessage(ConnectionInterface $from, NetworkMessage $message) {
if (!$this->verifyCsrfToken($from, $message)) {
throw new TokenMismatchException;
}
if (!$this->verifyUser($from, $message)) {
throw new \Exception('test');
}
...
}
private function verifyUser(ConnectionInterface $conn, NetworkMessage $message) {
$cookies = $conn->WebSocket->request->getCookies();
$laravel_session = rawurldecode($cookies['laravel_session']);
$id = $this->encrypter->decrypt($laravel_session);
$session = Session::find($id);
$payload = unserialize(base64_decode($session->payload));
$user_id = $payload['user_id'];
$user = User::find($user_id);
$characters = $this->characterService->allFrom($user);
$character_id = $message->getHeader()['character_id'];
return $characters->contains($character_id);
}
private function verifyCsrfToken($from, NetworkMessage $message) {
$header = $this->getHeaderToken($from);
return $this->verifier->tokensMatch($header, $message->getId());
}
代码肯定会更干净,但作为一个快速的黑客,它是有效的。我认为,与其使用会话模型,不如使用Laravel
DatabaseSessionHandler
我想我找到了一个解决方案。虽然不是很干净,但它做了它应该做的事情(我猜…)
WebSocket服务器由Artisan命令()启动。我将这些类注入命令:
light\Contracts\Encryption\Encrypter
-一个定制的CsrfTokenVerifier,它只比较两个字符串(将在其中放入更多的后续逻辑代码)App\Contracts\CsrfTokenVerifier
onMessage
方法中,我解析发送的消息,其中包含:
- 用户的CSRF令牌
- 用户的字符id
public function onMessage(ConnectionInterface $from, NetworkMessage $message) {
if (!$this->verifyCsrfToken($from, $message)) {
throw new TokenMismatchException;
}
if (!$this->verifyUser($from, $message)) {
throw new \Exception('test');
}
...
}
private function verifyUser(ConnectionInterface $conn, NetworkMessage $message) {
$cookies = $conn->WebSocket->request->getCookies();
$laravel_session = rawurldecode($cookies['laravel_session']);
$id = $this->encrypter->decrypt($laravel_session);
$session = Session::find($id);
$payload = unserialize(base64_decode($session->payload));
$user_id = $payload['user_id'];
$user = User::find($user_id);
$characters = $this->characterService->allFrom($user);
$character_id = $message->getHeader()['character_id'];
return $characters->contains($character_id);
}
private function verifyCsrfToken($from, NetworkMessage $message) {
$header = $this->getHeaderToken($from);
return $this->verifier->tokensMatch($header, $message->getId());
}
代码肯定会更干净,但作为一个快速的黑客,它是有效的。我认为,我不应该使用会话模型,而应该使用Laravel
DatabaseSessionHandler
,所以这就是我刚才解决这个问题的方法。在我的示例中,我使用的是Socket.IO,但我很确定您
$cookies = $conn->WebSocket->request->getCookies();
$laravel_session = rawurldecode($cookies['laravel_session']);
$id = $this->encrypter->decrypt($laravel_session);
if(Config::get('session.driver', 'file') == 'file')
{
$session = File::get(storage_path('framework/sessions/' . $id));
}
$session = array_values(unserialize($session));
return $session[4]; // todo: Hack, please think another solution
'domain' => 'your.domain.com',