【问题标题】:Storing application permissions in a database在数据库中存储应用程序权限
【发布时间】:2012-05-05 21:16:54
【问题描述】:

我正在为我们公司开发一个应用程序,该应用程序最终将有很多方法将用户限制在特定的部分/模块中。虽然应用程序仍然很小,但我想转向一种存储权限的新方法,随着应用程序的增长,该方法将保持易于维护和查询。

目前在我们的 MySQL 数据库中,我们有一个名为“user”的表,其中存储了用户的 ID、用户名和密码。在名为“user_acl”的单独表中如下:

user_acl_id
acl_root
acl_news_read
acl_news_write
acl_news_modify
acl_reports_read
acl_reports_write
acl_reports_modify
acl_users_read
acl_users_write
acl_users_modify

我们目前只有 3 个模块,但随着时间的推移会创建更多模块,并且需要为每个模块添加权限。

除了为每个权限创建一列之外,还有其他方法或存储此信息吗?

【问题讨论】:

    标签: php mysql arrays permissions store


    【解决方案1】:

    我会这样做。

    table name: permission
    columns: id, permission_name
    

    然后我可以使用多对多关系表为用户分配多个权限

    table name: user_permission
    columns: permission_id, user_id
    

    这种设计将允许我添加任意数量的权限,并将其分配给任意数量的用户。

    虽然上述设计符合您的要求,但我有自己的方法在我的应用程序中实现 ACL。我把它贴在这里。

    我的ACL实现方法是这样的:

    1. 将为用户分配一个角色(管理员、访客、员工、公众)
    2. 一个角色将被分配一个或多个权限(user_write、user_modify、report_read)等。
    3. 用户的权限将从他/她所在的角色继承
    4. 除了从角色继承的权限外,还可以为用户分配手动权限。

    为此,我提出了以下数据库设计。

    role
    I store the role name here 
    +----------+
    | Field    |
    +----------+
    | id       |
    | role_name |
    +----------+
    
    permission:
    I store the permission name and key here 
    Permission name is for displaying to user.
    Permission key is for determining the permission.
    +----------------+
    | Field          |
    +----------------+
    | id             |
    | permission_name |
    | permission_key  |
    +----------------+
    
    role_permission
    I assign permission to role here 
    +---------------+
    | Field         |
    +---------------+
    | id            |
    | role_id       |
    | permission_id |
    +---------------+
    
    user_role
    I assign role to the user here 
    +---------------+
    | Field         |
    +---------------+
    | id            |
    | user_id       |
    | role_id       |
    +---------------+
    
    user_permission
    I store the manual permission I may allow for the user here 
    +---------------+
    | Field         |
    +---------------+
    | id            |
    | user_id       |
    | permission_id |
    +---------------+
    

    这让我可以更好地控制 ACL。我可以允许超级管理员自己分配权限,等等。正如我所说,这只是为了给你一个想法。

    【讨论】:

    • 如何添加有关角色的额外信息,如管理员公共等?例如管理员有一些额外的东西要添加,比如公司名称..而用户没有这个字段?
    • 我会将信息存储在相关实体中,您可以在表中添加额外的列,如果您想为角色添加更多信息,那么您可以在角色表中添加额外的列,同样适用于用户表
    • 如果我有包含用户名和密码字段的用户表。这对所有用户都是通用的。我有成员表,其中包含一些额外的字段,如公司名称、地址等。我还有一些管理员信息。所以我需要为用户使用超类型/子类型关系和成员管理员?
    【解决方案2】:

    就像 Ibrahim 所说,专门为您的权限创建一个新表。为用户分配一个代表其权限级别的数值,例如 1 = 读取、2= 写入/读取、3 = 修改/写入/读取。然后在您的代码中,在允许用户执行特定任务之前检查适当的权限级别。如果它们没有所需的值(修改为 3 或写入 >=2),则您阻止该功能。

    【讨论】:

      【解决方案3】:

      我认为你应该有五个表:

      user
      user_x_profile
      profile
      profile_x_function
      function
      

      您设置了各种“通用”配置文件“查看者”、“员工”、“经理”等。

      您为每个要控制的对象设置一个“功能”条目。

      然后将函数链接到 profile_x_function 中的配置文件。

      然后为每个用户分配一个或多个配置文件。

      这减少了管理工作。假设您要添加另一个只有“经理”才能使用的功能 - 您只需在功能表中添加一个新条目,然后在“profile_x_function”表中添加一个条目,该条目链接到“经理”配置文件对经理配置文件的权限并且所有经理都可以使用。

      要查询访问权限,您需要一个五表连接,但您只选择一个权限属性。

      【讨论】:

        【解决方案4】:

        在一本非常著名的 MySQL 性能书籍High Performance MySQL中,作者特别提到了 ACL,可以使用像 SET 这样的数据类型。 他们使用以下示例来演示此类用例:

        CREATE TABLE acl (
            permissions SET('CAN_READ', 'CAN_WRITE', 'CAN_DELETE') NOT NULL
        );
        
        INSERT INTO acl VALUES ('CAN_READ,CAN_WRITE');
        SELECT permissions FROM acl WHERE find_in_set('CAN_READ', permissions);
        

        问题是,书中也提到,你不能轻易修改权限集(你必须使用ALTER TABLE),你也不能声明一个类型为SET的列作为索引,这可能导致性能问题。

        您还可以使用TINYINT 之类的东西来“包装” ACL 列表,缺点是它更难阅读以及编写SELECT 语句。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-27
          相关资源
          最近更新 更多