2012-01-09 48 views
0

我有X頁數,我希望爲每個頁面的頁面上的用戶設置權限。最初我想用bitmask。但是我意識到,如果我的頁數超過了一定數量(只能在MySQL unsigned BIGINT列中存儲64個頁面),那麼我的位掩碼的十進制等效值可能會變得太大。如何處理每個頁面的權限?

例如第64頁的十進制等值將是18,446,744,073,709,551,615,這只是讓它查看一頁。

那麼,你將如何去設置每頁,每個用戶的大量頁面的查看權限?

回答

3

爲什麼不把它們作爲多對多關係存儲在數據庫中?

user_id | page_id 
     1 |  1 
     1 |  2 
     2 |  1 
     2 |  3 

然後你就可以獲取頁面的用戶可以與SELECT * from users_pages WHERE user_id =?看,也可以決定是否允許用戶通過做SELECT * from users_pages WHERE page_id = ? and user_id = ?看到一個特定的頁面。

+0

這是不是會效率低下時,雖然規模? – 2012-01-09 15:55:20

+0

我不確定,但只要您爲這兩列設置了正確的索引,我想它會表現得相當好。 – vindia 2012-01-09 16:03:23

0

我會保持簡單,只需要PagesUsersUserPagePermissions表。最後一個只是頁面和用戶之間的地圖。

+0

你能詳細點嗎? – 2012-01-09 15:48:54

+0

@George查看vidnia的回答。這就是我的建議。 – 2012-01-09 15:52:58

1

我曾經看到過一個系統有一個類似於UNIX文件權限的用戶權限表 - 用戶可以讀取或寫入(編輯內容,它是CMS)此表中的任何頁面。 「頁面」由一個唯一的名稱標識,以便每個頁面都知道它是自己的名稱,當頁面被訪問時,它也知道哪個用戶正在訪問它,然後爲該頁面查找該用戶的權限,並顯示適當的編輯控件可用。

例子:

 
users 
    user_name (other columns) 
    ---------- 
    bob 
    lisa 
    ADMIN 

pages 
    page_id page_name (other columns) 
    ---------------------- 
    1  landing_page 
    2  products 
    3  corporate_about_us 

page_permissions 
    page_id user_name read write 
    ------------------------------ 
    1  Bob  Y 
    1  ADMIN  Y Y 
    2  ADMIN  Y  

這告訴我們,當ADMIN日誌中,並加載與ID = 1的網頁,他們將能夠進行更改網頁。然而,Bob不會。

我看到的實際系統比這更復雜一點(我非常肯定它實際上使用的是像rwx這樣的權限,而不是指示符列,我更喜歡),但我不記得詳細信息,所以我簡化。

您可以根據需要修改和自定義此方案。


如果你擔心引起由頁上百(或上千)以及存儲成千上萬的用戶准許記錄大量數據你實際運行測試permformance表明,這是一個重大的問題,你可以想出一個默認模式,例如:用戶總是隻讀到處,除非另有明確說明。然後,你可以這樣做:

 
users 
    user_name read_only_user (other columns) 
    --------------------------------------------- 
    bob   Y 
    lisa   Y 
    ADMIN 

pages 
    page_id page_name (other columns) 
    ---------------------- 
    1  landing_page 
    2  products 
    3  corporate_about_us 

page_permissions 
    page_id user_name read write 
    ------------------------------ 
    1  ADMIN  Y Y 
    2  ADMIN  Y  

這樣,你只需要存儲page_permission記錄用戶那裏read_only_user <> 'Y'。缺點是你需要更多的邏輯來處理這種設置。

0
<?php 
/** 
* acl_parser.inc.php 
* this is not a formal system of acls but a simplification 
* there are a number of attribuates known which are given 
* a value of 1, unknown attributes are numbered 0 
* then logical combinations of attributes are evaluated 
* 
* example of rule is: 
* personnel and manager not (plonker or temp) 
* note that rules are NOT case sensitive 
* @package simple_acl 
* @author Colin McKinnon <colin.mckinnon at google's public mail service> 
* @copyright 24th November 2007 
*/ 
/** 
* implements the parser 
* 
* IMORTANT: this method uses PHP's 'eval()' function - this has SERIOUS security implications unless you are 100% 
* sure of the provenance of data supplied to it. 
* The class has no built-in data access and must be populated with facts and a rule before evaluation 
*/ 
class acl_parser 
{ 
    /** 
    * @var array of fact=>value, private (use method to update) 
    * e.g. $fact['timenow']=date('His'); $fact['manager']=true; 
    */ 
    var $facts; 
    /** 
    * @var string the acl to check, private (use method to update) 
    * e.g. $rule="personnel and manager not (plonker or temp) and (timenow > '0900' and timenow < '1730')"; 
    */ 
    var $rule; 
    /** 
    * @var string the expression which was eval'd - for debugging 
    */ 
    var $rewrite; 
    /** 
    * constructor 
    * @param $facts array can be set/updated later 
    * @see var $facts 
    * @return null 
    */ 
    function acl_parser($facts=false) 
    { 
     // set up default subsitutions for operators.... 
     $this->facts=array('and' => '*', // must come between expressions 
      'or' => '+', // must come between expressions 
      'not' => '!', // must come before expression 
      'true' => '1' 
      ); 
     // did we get some data to set up? 
     if (is_array($facts)) { 
      foreach ($facts as $name=>$val) { 
       $this->add_fact($name, $val); 
      } 
     } 
     $this->rule===false; 
    } 
    /** 
    * wrapper to control access to $this->rule 
    * @param string 
    * @return bool - true if successful 
    * 
    * could be used to set site specific policies relating to rules - e.g. no less than/greater than 
    */ 
    function set_rule($rule) 
    { 
     $this->rule=$rule; 
     return(true); 
    } 
    /** 
    * set a single fact for addition 
    */ 
    function add_fact($name, $value) 
    { 
     $this->facts[$name]=$value; 
    } 
    /** 
    * evaluate the rule applying the known facts 
    * @return bool 
    */ 
    function test($rule=false) 
    { 
     if ($rule!=false) { 
      $this->rule=$rule; 
     } 
     if (($this->rule===false) || (!count($this->facts))) { 
      trigger_error("acl_parser not initialised with rule and facts"); 
      return(false); 
     } 
     $match=array(); 
     $replace=array(); 
     foreach ($this->facts as $name=>$val) { 
      $match[]='/([^a-z]|^)(' . $name . ')([^a-z]|$)/i'; 
      $replace[]='${1}' . $val . '${3}'; 
     } 
     // this macro gets added on end to pick up on undefined elements 
     $match[]='/[a-z]+/i'; 
     $replace[]='0'; 
     $rewrite=preg_replace($match,$replace,$this->rule); 
    $this->rewrite=$rewrite; 
     return((bool)eval("return($rewrite);")); 
    } 
} 

?> 
+0

我確定這很棒......但它做了什麼? – 2012-01-09 16:29:25

+0

它使用一組事實評估任意表達式 - 請參閱示例 – symcbean 2012-01-10 12:57:50