
多租户(Multi-Tenancy)是一种软件架构和服务模式,指的是在一个软件实例中,多个租户(可以是企业、组织、个人等)能够共享相同的软件应用程序和底层基础设施,同时每个租户的数据和配置相互隔离,就像多个租户共同使用同一栋大楼,但各自拥有独立的房间和隐私。
本教程使用
共享数据库和架构
在这种模式下,所有的租户(即SaaS平台的客户)共享同一个物理数据库服务器或数据库实例。这意味着,尽管每个租户都有自己的数据,但这些数据都存储在同一个数据库文件或数据库集群中。这样做的好处是可以减少硬件资源和维护成本,因为不需要为每个租户单独设置和维护数据库实例。

在多租户环境中数据库必须为每个租户分别存储数据并确保数据隔离。通常使用以下两种方式实现:
tenant_id这一列,用于区分不同租户的数据。CREATE TABLE`resty_tenant` (
`id`bigint(20) unsignedNOTNULL AUTO_INCREMENT,
`name`varchar(50) COLLATE utf8mb4_unicode_ci NOTNULL,
`description`varchar(255) COLLATE utf8mb4_unicode_ci DEFAULTNULL,
`created_time`int(11) unsignedNOTNULLDEFAULT'0',
`updated_time`int(11) unsignedNOTNULLDEFAULT'0',
PRIMARY KEY (`id`),
UNIQUEKEY`name` (`name`)
) ENGINE=InnoDBDEFAULTCHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='租户表';
PHP-Casbin 是一个用 PHP 语言打造的轻量级开源访问控制框架,支持 ACL、RBAC、ABAC 多种模型。目前在 GitHub 开源。PHP-Casbin 采用了元模型的设计思想,支持多种经典的访问控制方案,如基于角色的访问控制 RBAC、基于属性的访问控制 ABAC 等。
PHP-Casbin 不仅提供了全局的RBAC的权限模型,而且还支持特定域的权限模型。特定租户/域的角色意味着当用户在不同的租户/域中时,用户可以拥有不同的角色,亦拥有不同的权限策略。在大型项目中,特别是在像SaaS PaaS这种云服务中,不同的租户需要拥有独立的权限控制,这就非常有用。
以多商户电商平台为例,该平台中的商户即为租户。每个商户都拥有自身的管理团队,能够为团队成员分配不同角色,并自定义相应权限。各商户的数据在逻辑层面完全隔离,然而共享电商平台的其余资源。
在这个电商平台架构下:
每个商户作为独立租户,其内部的用户与商品数据相互隔离,并且各自拥有一套独立运作的权限控制系统。这种多租户模式确保了每个商户能够在共享平台资源的基础上,实现个性化管理与数据安全隔离。
rbac_with_domains_model.conf 模型文件
[request_definition]
r=sub,dom,obj,act
[policy_definition]
p=sub,dom,obj,act
[role_definition]
g=_,_,_
[policy_effect]
e=some(where(p.eft==allow))
[matchers]
m=g(r.sub,p.sub,r.dom)&&r.dom==p.dom&&r.obj==p.obj&&r.act==p.act
通过上面的模型配置,可以看出,相比普通的RBAC模型,它多了一个dom参数,这个dom就是上文所说的商户(domain)。
在[role_definition]中g = _, _, _,有三个占位符,分别代表:用户、角色、租户/域。
在[matchers]中的g(r.sub, p.sub, r.dom)就是判断用户、角色和租户/域之间的关系。
rbac_with_domains_policy.csv策略文件
p, admin,tenant1,goods1,read
p,admin,tenant1,goods1,write
p,admin,tenant2,goods2,read
p,admin,tenant2,goods2,write
g,user1,admin,tenant1
g,user2,admin,tenant2
上面分别定义了商户1(tenant1)和商户2(tenant2)的管理员权限策略,并且在各自的租户下赋予了user1和user2的管理员(admin)角色。
安装PHP-Casbin依赖包
composer require casbin/casbin
实例化了一个决策器(Enforcer)
<?php
/**
* @desc 决策器(Enforcer)
* @author Tinywan(ShaoBo Wan)
*/
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use Casbin\Enforcer;
$enforcer = new Enforcer('./rbac_with_domains_model.conf','./rbac_with_domains_policy.csv');
var_dump(
$enforcer->enforce('user1', 'tenant1', 'goods1', 'read'), // true
$enforcer->enforce('user1', 'tenant1', 'goods1', 'write'), // true
$enforcer->enforce('user1', 'tenant2', 'goods2', 'read'), // false
$enforcer->enforce('user1', 'tenant2', 'goods2', 'write'), // false
);
可以看出,在 商户1 下,用户1 对 商品1 拥有read和write的,但他对商户2 下的商品是没有权限的。
同样,下面验证 商户2 的权限,在 商户2 下,用户2 对 商品2 有权限,而对商户1 是没有权限的。
var_dump(
$enforcer->enforce('user2', 'tenant1', 'goods1', 'read'), // false
$enforcer->enforce('user2', 'tenant1', 'goods1', 'write'), // false
$enforcer->enforce('user2', 'tenant2', 'goods2', 'read'), // true
$enforcer->enforce('user2', 'tenant2', 'goods2', 'write'), // true
);
在开发面向企业的 SaaS 云服务平台已成趋势,而多租户权限控制的设计则是该类平台的核心要素。多租户模式让多个租户能共享相同的资源与组件,同时实现租户间的数据隔离,不仅具备极高的成本效益,还拥有出色的灵活性与可扩展性。
借助PHP语言打造的轻量级开源访问控制框架PHP-Casbin,能够快速完成多租户权限控制模型的设计与开发,为 SaaS 云服务平台的高效搭建与稳定运行提供有力支持。