Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Laravel,WebSockets-验证服务器上的用户_Php_Session_Laravel_Eloquent_Ratchet - Fatal编程技术网

Php Laravel,WebSockets-验证服务器上的用户

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令牌,但

我目前遇到了使用LaravelRachetPHP在服务器上处理用户身份验证的问题

到目前为止,我尝试的是:
  • 我将会话的驱动程序类型更改为数据库,给了我一个id和有效负载列。使用
    \Session::getId()
    返回一个40个字符的字符串。 WebSocket连接发送的cookie信息确实包含XSRF-TOKEN和laravel_会话,两者都包含>200个字符串。用户会话的数据库ID与
    \session::getId()
    返回的ID不同

  • 我已经通过websocket消息发送了当前的CSRF令牌,但是我不知道如何验证它(内置的验证器使用请求-我在websocket服务器范围内没有)

通用用例: 用户在线程中发布注释。然后,发送对象的有效负载将是:

  • 验证用户的东西(ID或令牌)
  • 评论本身
如果您要发送用户ID,任何人都可以修改数据包并在另一个用户下发送消息

我的用例: 用户可以有n个字符。角色具有化身、id、名称等。 用户仅用于:

  • 在服务器上进行身份验证
  • 访问他的角色,从而对他的角色执行基本CRUD操作
我还有一个表位置-一个“虚拟的地方”,一个角色可以在。。。所以我得到了角色位置之间的一对一关系。然后,用户(角色)可以通过websocket在某个位置发送消息。消息将插入服务器上的数据库中。在这一点上,我需要知道:

  • 如果用户经过身份验证(csrf令牌?)
  • 如果用户是角色的所有者(用另一个用户的角色id欺骗请求非常简单)

如果您需要更多信息,请告诉我。

我想我找到了解决方案。虽然不是很干净,但它做了它应该做的事情(我猜…)

WebSocket服务器由Artisan命令()启动。我将这些类注入命令:

  • light\Contracts\Encryption\Encrypter
  • App\Contracts\CsrfTokenVerifier
    -一个定制的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
  • App\Contracts\CsrfTokenVerifier
    -一个定制的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
  • App\Contracts\CsrfTokenVerifier
    -一个定制的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
  • App\Contracts\CsrfTokenVerifier
    -一个定制的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',