2015-10-18 4 views
17

私はsocket.ioのチャットで少し遊んでいました。質問があります:管理者ユーザーと一般ユーザーを区別するにはどうすればよいですかチャットルーム?私は、管理人に、人を蹴ったり禁止したりする権限を持たせたいが、私のユーザーはそうしないようにしたい。socket.io chatでsymfonyのユーザーロール/グループを区別する方法

私はアプリケーションを開発するためにSymfonyを使用しています。チャットユーザーにはそのユーザーデータベースを使用したいと思います。私はsymfonyアプリケーションのユーザーにFOSUserBundleを使用しています。それらは複数のグループに分割されているので、私はadminグループなどを持っています。

adminグループにはROLE_ADMINが含まれています。つまり、その内部の各ユーザーにその役割が割り当てられています。これは管理者グループであり、このグループの各ユーザーはチャットルーム内の他のユーザーを禁止、蹴る、ミュートするなどの権限を持つ必要があります。

チャットで私のSymfonyユーザーを使用するために、私は彼らのセッションを取得するためのRedisに読んでいましたが、私は私の管理ユーザーと通常のユーザーとの違いを作る方法を正確にはわかりません。通常のユーザーがサーバーにアクセスしてユーザーがアクセスできない何かを要求しないようにするにはどうすればよいですか?誰でもリクエストを行うことができますが、のリクエストは、ApacheサーバーのMySQLデータベースに格納されているユーザーからのものであることを確認できますか?

symfonyでない場合、これは通常のPHPアプリケーションでどのように行うことができますか?最後に、管理者の定義方法は関係ありませんが、ノードサーバーに接続する方法、ノードサーバーをユーザーデータベースと連携させる方法については問題ありません。

ユーザーのデータを単純に暗号化してノードサーバーに送信し、そこから復号化するという考えがありました。 2台のサーバだけが秘密鍵を知っているので、クライアントが暗号化されたデータを手にしても、他のクライアントに対して要求を行うことはできません。私はいくつかのIPチェックとタイムスタンプを行うかもしれません。ノードサーバー上の復号化されたデータを使用して、ユーザーが管理者であるかどうかを知らせ、特定の要求を送信することができます。これは良いアイデアですか、それとも良い方法ですか?

+0

多分、http://stackoverflow.com/questions/26176359/socket-io-connect-role-authenticationの複製 – pregmatch

+0

重複していません。この質問はかなり具体的です。 – Bogdan

答えて

3

ユーザーのデータを単純に暗号化してノードサーバーに送信し、そこから復号化するという考えがありました。 2台のサーバだけが秘密鍵を知っているので、クライアントが暗号化されたデータを手にしても、他のクライアントに対して要求を行うことはできません。基本的な考え方だ

どうすればいいですか? 私はJWTのようなものを使って、userIdをノードアプリケーションに送信します。私はjwtの署名が本当に本当のユーザーによって発行されたことを確認するためにのみ気にするので、暗号化する必要はありません。

その後、userIdを使用して、サーバー側にを呼び出して、ユーザーの役割を確認します。

は手の込んだ:

  • ノードアプリとPHPのアプリがJWTトークンに署名する共有秘密を使用します。
  • PHPアプリケーションは、生成されたトークンをフロントエンドに公開します。
  • socket.ioクライアントは、トークンを認証の一部としてノードアプリケーションに送信します。 PHPアプリケーションから「禁止」の要求をhanldeできnodejsアプリケーションでのWebサービスのエンドポイントを作成し、そのユーザーID
  • で開かれたソケットのリストを保つ

    • を禁止処理する方法

  • nodejsアプリケーションがこのような要求を受け取った場合、そのユーザーIDに基づいてソケットをルックアップして接続を閉じます。
+0

うわー、私たちは、WebTokenを使用することが行く方法であることを理解しました。 –

3

私は通常votersコールでユーザーの役割を確認するサービスを作成します(必要に応じて提供することができます)。 "このユーザーはこの特定の投稿を更新できますか?

コンフィグ

company.navigation.security_access: 
    class: Company\NavigationBundle\Services\SecurityAccessManager 
    arguments: 
     - @security.authorization_checker    
     - @security.token_storage 

サービスコード

namespace Company\NavigationBundle\Services; 
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; 
use Symfony\Component\Security\Core\Exception\AccessDeniedException; 

class SecurityAccessManager 
{ 
    private $authorizationChecker; 
    private $tokenStorage; 
    private $debug; 

    public function __construct(
      AuthorizationCheckerInterface $authorizationChecker, 
      TokenStorage $tokenStorage) 
    {  
     $this->authorizationChecker = $authorizationChecker; 
     $this->tokenStorage = $tokenStorage; 
     $this->debug = true; 
    } 

    // ************************************************************************* 
    // User 
    // ************************************************************************* 

    public function getUser() 
    { 
     return $this->tokenStorage->getToken()->getUser();   
    } 

    public function getUserId() 
    { 
     return $this->tokenStorage->getToken()->getUser()->getId();   
    } 

    public function isAuthenticatedUser() 
    {  
     return $this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED'); 
    }  

    // ************************************************************************* 
    // Roles checker 
    // ************************************************************************* 

    public function isAdmin() 
    { 
     if($this->authorizationChecker->isGranted('ROLE_ADMIN') !== true) { 
      return false; 
     } else { 
      return true;   
     } 
    }  

    public function checkRightAdmin() 
    { 
     if($this->authorizationChecker->isGranted('ROLE_ADMIN') !== true) { 
      throw new AccessDeniedException('Unauthorised access! '.($this->debug ? __FUNCTION__ : null)); 
     } 

     return true;   
    } 

    public function checkUserHasRightToEditPost($postId) 
    { 
     // Check if user has right to modify the post 
     if ($this->authorizationChecker->isGranted('is_user_has_right_to_edit_post', $postId) === false) { 
      throw new AccessDeniedException('Unauthorised access! '.($this->debug ? __FUNCTION__ : null)); 
     } 

     return true; 
    } 
} 

次に、あなたのコントローラのアクションで、あなたがチェックすることができ、ユーザーの権利

namespace Company\YourBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

class YourBunbleController extends Controller 
{ 
    /** 
    * Get the service 
    * @return \Company\NavigationBundle\Services\SecurityAccessManager 
    */ 
    private function getService() 
    {   
     return $this->get('company.navigation.security_access'); 
    } 

    public function updatePostAction(Request $request, $postId) 
    { 
     // Throw 403 if user has no admin rights 
     $this->getService()->checkRightAdmin(); 

     // Throw 403 if user has no rights to update the post 
     $this->getService()->checkUserHasRightToEditPost(); 

     //OK, you can update database 
     ... 
    } 
} 
+0

これは本当にフォーマットのよい回答ですが、私の問題は解決しません。私はすでに権限をチェックするために有権者を作っており、ユーザーのROLEをチェックすることもできますし、グループをチェックすることもできます。私の問題は、これらの役割をnode.jsサーバーに渡す方法でした。そのため、チャットルームを制御できます。そして、ノードとmysqlデータベースで同じユーザーを持つ方法。たとえば、管理者は特定のユーザーにアクセスを禁止しますか? –

+0

バニングはソケット接続を即座に閉じるべきであるので、ノードはデータベースと何らかの関係を持ち、Symfonyアプリケーションと並行して動作する必要があります。 –

関連する問題