简体   繁体   English

在php应用程序中实现基于角色的访问控制

[英]Implementing Roles based access control in php application

I have been working on a PHP application for my college that requires role based access control. 我一直在为我的大学开发一个PHP应用程序,该应用程序需要基于角色的访问控制。 The approach I followed was to create a separate MySQL user for each role. 我遵循的方法是为每个角色创建一个单独的MySQL用户。 So every role had a separate db user. 因此,每个角色都有一个单独的数据库用户。 Each of these db users had privileges on a minimal set of tables that was required for the role. 这些数据库用户中的每个用户都具有角色所需的最小表集的特权。

Now, my question is whether this is infact a proper way to handle a role based application. 现在,我的问题是这实际上是否是处理基于角色的应用程序的正确方法。 The reason I have come into this doubt is because now when the time has come to get the system online (with GoDaddy hosting) I found out that they do not allow creating users with table specific privileges. 我之所以对此表示怀疑,是因为现在是时候让该系统在线(带有GoDaddy托管)了,我发现他们不允许创建具有表特定特权的用户。 Infact they don't even allow creating users directly through a SQL script(Role creation on the system involved creating users through a php script executing a SQL command). 实际上,他们甚至不允许直接通过SQL脚本创建用户(系统上的角色创建涉及通过执行SQL命令的php脚本创建用户)。

Due to this I am now thinking if my approach was infact the correct approach or not. 因此,我现在正在考虑我的方法是否正确。 What is the standard way of implementing such role based systems? 实现这种基于角色的系统的标准方法是什么?

This was my first live project so I don't really had much previous experience in terms of actually delivering a real project. 这是我的第一个实时项目,因此我在实际交付实际项目方面并没有太多的经验。

Unless you are not a hoster you probably don't want to create database users dynamically via scripts. 除非您不是托管人,否则您可能不想通过脚本动态创建数据库用户。 Think about it: 考虑一下:

A database user is a component that interacts with your application and not with your end-users. 数据库用户是与您的应用程序而非最终用户进行交互的组件。

So stick with one database for your application and use dedicated tables to build your ACL. 因此,请为您的应用程序保留一个数据库,并使用专用表来构建您的ACL。 Your database schema could look like this: 您的数据库架构可能如下所示:

users( id:pk, name )
roles( id:pk, name )
permissions( id:pk, key, description )
permission_role( permission_id:fk, role_id:fk )
role_user( role_id:fk, user_id:fk )

You basically have three things here: 您基本上在这里有三件事:

  • Users : Nothing special. 用户 :没什么特别的。 Just a user that can be uniquely defined by it's id 只是可以由其ID唯一定义的用户
  • Permissions : Basically just a store of keys that will be queried within your script to check for permissions. 权限 :基本上只是一个密钥存储区,这些密钥将在脚本中查询以检查权限。
  • Roles : The glue between Users and Permissions. 角色 :用户和权限之间的黏合剂 The sum of roles that a User belongs to and it's permissions will define the entirety of what a user is permitted to do and what not. 用户所属的角色及其权限的总和将定义允许用户执行的全部操作以及不允许执行的操作的全部。

That's the basic setup. 这是基本设置。 The other tables are just helper tables to join pieces together. 其他表只是将各个部分连接在一起的助手表。

Your code handles the rest. 您的代码将处理其余部分。 Setup a (or better more) class that do the heavy lifting. 设置一个(或更好的)类来完成繁重的工作。 Then pass an instance of your ACL to your User class (other implementations are of course possible. See at the bottom of the post). 然后将您的ACL实例传递给User类(当然可以实现其他实现。请参见文章底部)。

<?php 

class Acl implements AclInterface {

    public function hasPermissionTo( $action )
    {
        // Query DB and check if a record exists
        // in the role_user table where the 
        // user_id matches with the current user
        // and join the role_id with `roles` and then
        // with `permission_role` to see if the user
        // is permitted to perform a certain action
    }

}

class User {

    protected $acl;

    public function __construct( AclInterface $acl )
    {
        $this->acl = $acl;
    }

    public function hasPermissionTo( $action )
    {
        return $this->acl->hasPermissionTo( $action );
    }

}

You should get the basic concept. 您应该了解基本概念。 The actual implementation is up to you. 实际的实施取决于您。 Things you may want to consider: 您可能需要考虑的事项:

  • Do you want your ACL to be part of your User or rather a standalone component? 您希望ACL成为User一部分,还是成为独立的组件?
  • How do you want to pass the current user to the ACL? 您想如何将当前用户传递给ACL? Do you want to pass an instance of the current user to the ACL, or rather only the user ID? 您要将当前用户的实例传递给ACL还是仅传递用户ID?

Those question depend on what you like and on your architecture. 这些问题取决于您喜欢什么以及您的体系结构。 Happy Coding! 编码愉快!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM