Yii2多租户架构 - 选择正确的数据库

时间:2016-12-22 14:53:50

标签: yii2 multi-tenant

我正在使用Yii2构建应用程序,我正在使用多租户架构。所以...每个客户都有自己的数据库(相同的结构)。

到目前为止我做了什么:

  • 我在config / web.php文件中声明了所有不同的数据库
  • 我有一个master数据库,它将每个用户对应到他的数据库。因此,当有人登录时,应用程序会知道应该使用哪个数据库。

我做了什么,但我不确定:

我使用以下代码创建了一个文件组件/ ActiveRecord.php:

<?php
namespace app\components;
use Yii;

class ActiveRecord extends \yii\db\ActiveRecord {

    public static function getDb() {
        if (isset($_SESSION['userdb'])) {
            $currentDB = $_SESSION['userdb'];
            return Yii::$app->get($currentDB);
        }
    }

}?>

所以...在登录时我将数据库保存在会话中,并在上述文件中扩展了默认的ActiveRecord,我覆盖了getDb函数,我选择了自己的。随后,我更改了所有模型,以便扩展我的ActiveRecord。

我不确定这种策略是否正确,但它几乎可行。

问题出在哪里:

一切正常,除了...... RBAC!对于RBAC,我使用yii2-rbac扩展。问题是用户没有从他的数据库中获取角色,而是从config / web.php文件中的第一个声明的数据库获取角色。因此,无论登录用户如何,都会使用第一个数据库。

问题(S):

  1. 我该如何解决这个问题?您是否知道为登录用户提供角色的文件在哪里?
  2. 奖金问题:您认为这种策略是错误的吗?如果是这样,你会建议什么?
  3. 非常感谢您的时间和支持。

2 个答案:

答案 0 :(得分:2)

问题#1:如何解决此问题?您是否知道为登录用户提供角色的文件在哪里?

  

我建议您使用yii2管理员扩展程序(https://github.com/mdmsoft/yii2-admin)来解决您的问题,它是管理用户角色的最佳扩展。使用此链接可以更好地理解(https://github.com/mdmsoft/yii2-admin/blob/master/docs/guide/configuration.md

  • 按照以上网址安装以上内容,或者只在您的composer.json文件中添加&#34; mdmsoft / yii2-admin&#34;:&#34; ~2.0&#34; 并运行作曲家更新
  • 成功安装此扩展程序后,运行迁移以创建RBAC表,如果已经有,则跳过它。 yii migrate --migrationPath=@yii/rbac/migrations

  • 您必须在main.php中进行一些配置,告诉您的应用程序有关公共路由的信息,并且所有其他应用程序路由系统都会在其上实现RBAC。

  • 这是你必须在main.php文件中添加的内容。

    'components' => [], 'as access' => [ 'class' => 'mdm\admin\components\AccessControl', 'allowActions' => [ 'site/login', // add or remove allowed actions to this list 'site/logout', 'site/error', 'site/index', ] ]

  • 以上设置将告诉您的应用程序使登录,注销,错误和索引功能在站点控制器下是公共的,并且所有其他应用程序路由需要具有RBAC分配才能执行操作。

  • 在我的情况下,
  • main.php 存在于backend / config / main.php中,你可以根据你的要求使用可能是共同的/ config / main.php

问题2:奖金问题:您认为这种策略是错误的吗?如果是这样,你会建议什么?

我认为您的方法不可扩展,我建议您创建一个主数据库,并将其用于您的应用程序租户及其数据库。

  • 使用租户名称,数据库必需参数
  • 在主数据库中设置租户表
  • 在您的应用程序中建立主数据库连接,用于获取所有租户,并存储来自主数据库的数据库连接。

    'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=127.0.0.1;dbname=master-db', 'username' => 'root', 'password' => 'root', 'charset' => 'utf8', ]

  • 现在,在登录页面显示租户列表以选择他们的信息如果您使用每个租户的唯一域,您也可以使用域名。如果您使用的是唯一域,那么您必须在主数据库中存储具有租户信息的域名,以便能够根据域获取租户信息。

//在成功登录页面上设置会话值读取用户域并从主数据库获取租户信息并添加到会话中。

``
  $tenant = Tenant::findOne(Yii::$app->request->post('tenant_id'));
  Yii::$app->session->set('DB_HOST', $tenant->DB_host);
  Yii::$app->session->set('DB_USER', $tenant->DB_username);
  Yii::$app->session->set('DB_PASS', $tenant->DB_password);
  Yii::$app->session->set('DB_NAME', $tenant->DB_name);
``
  • 获得租户信息后,您可以从主数据库获取租户并将其数据库设置添加到SESSION。

  • 创建 BaseModel.php 类,并使用所有应用程序模型类对其进行扩展。

  • 在您 BaseModel.php 中添加以下方法,以根据登录页面中的域或租户选择建立运行时数据库连接。

public static function getDb(){ if ( Yii::$app->session->get('DB_HOST') ){ $host = Yii::$app->session->get('DB_HOST'); $dbName = Yii::$app->session->get('DB_NAME'); $dsn = "mysql:host=$host;dbname=$dbName"; Yii::$app->db->dsn = $dsn; Yii::$app->db->username = Yii::$app->session->get('DB_USER'); Yii::$app->db->password = Yii::$app->session->get('DB_PASS'); return Yii::$app->db; } }

  • 通过执行此操作,您可以选择将多个租户从后端添加到主数据库,并且可以在您的应用程序中自动使用。

我相信这些信息对您有所帮助。

干杯!!!

答案 1 :(得分:0)

以下是dbmanager的文档。

如果您想从其他数据库获取rbac信息,这应该可以。

在config文件夹中,创建一个名为rbacdb.php的文件。添加以下内容:

<?php

return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=<db host or ip>;dbname=<dbname>',
'username' => '<dbuser>',
'password' => '<dbPassword>',
'charset' => 'utf8',
];

然后转到配置文件并找到authmanger部分。它应该是这样的:

'authManager' => [
'class' => 'yii\rbac\DbManager',
'db'=> require(__DIR__ . '/rbacdb.php'),
'assignmentTable'=>'<tableName>',
'itemChildTable'=>'<tableName>',
'itemTable'=>'<tableName>',
'ruleTable'=>'<tableName>'
]

编辑:重读你的帖子后......每个用户都不需要自己的rbac表/架构。使用Yii所具有的系统。