2015-10-18 67 views
17

我一直在玩socket.io的聊天,我有一個問題:如何區分管理員用戶和普通用戶聊天室?我希望管理員擁有踢人和禁止人的權力,但我的用戶不會。如何區分socket.io中的Symfony用戶角色/組聊天

我正在使用Symfony來開發我的應用程序,並且我想爲聊天用戶使用其用戶數據庫。我爲我的Symfony應用的用戶使用FOSUserBundle。他們分成多個組,所以我有admin組和其他組。

admin組擁有ROLE_ADMIN這意味着其中的每個用戶都具有該角色。這是管理員組,並且該組中的每個用戶應該有權禁止,踢,靜音等聊天室中的其他用戶。

爲了在聊天中使用我的Symfony用戶,我一直在閱讀Redis以獲得他們的會話,但我不確定如何區分我的管理員用戶和普通用戶。如何防止普通用戶向服務器發出請求,以執行用戶無法訪問的內容?因爲任何人都可以請求,但是如果這些請求來自存儲在Apache服務器上MySQL數據庫中的用戶,我如何驗證這些請求?

如果不是Symfony,那麼這可以在普通的PHP應用程序中完成?最後,管理員如何定義並不重要,但是如何將他連接到節點服務器以及如何使節點服務器與我的用戶數據庫一起工作。

我有一個簡單的加密和發送用戶數據到節點服務器的想法,然後解密它。只有兩臺服務器知道私鑰,因此即使客戶端掌握了加密數據,他也無法向另一客戶端發出請求。我可能會做一些IP檢查和時間戳。節點服務器上的解密數據可用於說明用戶是否是管理員並允許他發送某些請求。這是一個好主意還是有更好的方法?

+0

可能重複http://stackoverflow.com/questions/26176359/socket-io-connect-role-authentication – pregmatch

+0

不是重複的。這個問題si非常具體。 – Bogdan

回答

3

我有一個簡單的加密和發送用戶數據到節點服務器的想法,然後在那裏解密它。只有兩臺服務器知道私鑰,因此即使客戶端掌握了加密數據,他也無法向另一客戶端發出請求。

這就是基本的想法。

我該怎麼做? 我會使用類似JWT的東西來發送userId給節點應用程序。不必加密,因爲我只關心jwt簽名以確保請求確實由真實用戶發佈。

之後,使用userId我會做一個服務器端調用PHP應用程序來檢查用戶的角色。

要闡述:

  • 節點應用程序和PHP應用程序將使用一個共享的祕密簽署JWT令牌。
  • PHP應用程序會將生成的令牌公開給前端。
  • socket.io客戶端會將令牌作爲身份驗證的一部分發送給節點應用程序。

如何處理禁止

  • 保持打開套接字的列表與他們的用戶ID
  • 創建在的NodeJS應用程序,它可以hanlde從PHP應用程序中的「禁令」的請求一個web服務端點。
  • 當nodejs應用程序接收到這樣的請求時,根據用戶標識查找套接字並關閉連接。
+0

是的,我們發現使用WebToken是最好的選擇。 –

3

我通常會創建一個SecurityAccessManager服務來檢查用戶的角色與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

這是一個格式良好的答案,但它不能解決我的問題。我已經讓選民檢查了權限,我也可以檢查用戶角色,或者我可以檢查組。我的問題是如何將這些角色傳遞給node.js服務器,因此它可以控制聊天室。以及如何在節點和我的mysql數據庫上擁有相同的用戶。例如,管理員如何禁止訪問某些用戶? –

+0

禁止也應該立即關閉套接字連接,因此節點必須與數據庫有某種關係,並與Symfony應用程序並行工作。 –