thinksaydo/envtenant

Laravel 多租户感知 Artisan。

2.2.10 2016-12-22 03:11 UTC

This package is not auto-updated.

Last update: 2020-11-02 16:03:42 UTC


README

警告:该项目现已停止维护,将不再更新。如果您想使用它,代码相当简单,因此请随意分支并按您的需求继续。

2.2.10 版本更改

  • Laravel 5.3 支持。

2.2.6 版本更改

  • 将连接列设置为 'pending' 以阻止租户访问,直到管理员批准。

2.2.3 版本更改

  • 添加了获取所有租户的能力
  • 添加了激活和运行所有租户模型回调的能力
  • 添加了通过 ID 获取租户的能力,而不是子域或域名(example.com/{tenantId})

2.2.2 版本更改

  • 删除了通用监听器
  • 删除了公共 setDefaultConnection 方法
  • 将解析器注册改为 app('tenant')
  • 添加 TenantContract 以启用自定义模型
  • 更新文档

The Laravel 5.2 EnvTenant package enables you to easily add multi-tenant capabilities to your application. This package is designed using a minimalist approach providing just the essentials - no views, routes, or configs. Just drop it in, run the migration, and start adding tenants. Your applications will have access to current tenant information through the dynamically set config('tenant') values. Optionally, you can let applications reconnect to the default master database so a tenant could manage all tenant other accounts for example. And, perhaps the best part, Artisan is completely multi-tenant aware! Just add the --tenant option to any command to run that command on one or all tenants. Works on migrations, queueing, etc.!

EnvTenant 还提供 TenantContract、触发 Laravel 事件和抛出 TenantNotResolvedException,因此您可以轻松添加自定义功能并根据需要调整。

Laravel EnvTenant 最初由 @leemason 的 Laravel Tenantable 项目分支而来。Lee 应该被归功于在 Artisan 中全局添加 --tenant 选项所做的许多艰苦工作,并为这个想法提供了灵感。这个项目与 Tenantable 的区别在于它管理数据库连接设置的方法。Tenantable 在数据库中存储设置并提供无限域名。EnvTenant 依赖于您的 ENV 和数据库配置,并在表中仅存储连接名称,每个租户只允许一个子域和域名,这对于大多数应用程序来说通常已经足够。当找不到租户时,EnvTenant 也会抛出 TenantNotResolvedException,您可以捕获它。

简单安装和用法

Composer 安装

composer require thinksaydo/envtenant:2.2.*

然后运行 composer dump-autoload。

安装租户数据库表

artisan migrate --path /vendor/thinksaydo/envtenant/migrations

安装服务提供者

ThinkSayDo\EnvTenant\TenantServiceProvider::class,

创建租户(仅使用标准 Eloquent 模型)

$tenant = new \ThinkSayDo\EnvTenant\Tenant();
$tenant->name = 'ACME Inc.';
$tenant->email = 'person@acmeinc.com';
$tenant->subdomain = 'acme';
$tenant->alias_domain = 'acmeinc.com';
$tenant->connection = 'db1';
$tenant->meta = ['phone' => '123-123-1234'];
$tenant->save();

完成!简约、简单。每次您的应用程序通过 http://acme.domain.comhttp://acmeinc.com 访问时,默认数据库连接将设置为 "db1",表前缀将切换到 "acme_",config('tenant') 将设置租户详情,让您可以从视图或应用程序中访问值。

高级 EnvTenant 用法

Artisan

// migrate master database tables
php artisan migrate

// migrate specific tenant database tables
php artisan migrate --tenant=acme

// migrate all tenant database tables
php artisan migrate --tenant=*

所有Artisan命令都支持--tenant选项。

租户

\ThinkSayDo\EnvTenant\Tenant类是一个简单的Eloquent模型,提供基本的租户设置。

$tenant = new \ThinkSayDo\EnvTenant\Tenant();

// The unique name field identifies the tenant profile
$tenant->name = 'ACME Inc.';

// The non-unique email field lets you email tenants
$tenant->email = 'person@acmeinc.com';

// The unique subdomain field represents the subdomain portion of a domain and the database table prefix
// Set subdomain and alias_domain field to NULL to access tenant by ID instead
$tenant->subdomain = 'acme';

// The unique alias_domain field represents an alternate full domain that can be used to access the tenant
// Set subdomain and alias_domain field to NULL to access tenant by ID instead
$tenant->alias_domain = 'acmeinc.com';

// The non-unique connection field stores the Laravel database connection name
$tenant->connection = 'db1';

// The meta field is cast to an array and allows you to store any extra values you might need to know
$tenant->meta = ['phone' => '123-123-1234'];

$tenant->save();

租户解析器

\ThinkSayDo\EnvTenant\TenantResolver类负责在Web和Artisan访问期间解析和管理活动租户。您可以使用app('tenant')访问解析器类。

// get the resolver instance
$resolver = app('tenant');

// check if valid tenant
$resolver->isResolved();

// get the active tenant (returns Tenant model or null)
$tenant = $resolver->getActiveTenant();

// get all tenants (returns collection of Tenant models or null)
$tenants = $resolver->getAllTenants();

// activate and run all tenants through a callback function
$resolver->mapAllTenants(function ($tenant) {});

// reconnect default connection enabling access to "tenants" table
$resolver->reconnectDefaultConnection();

// reconnect tenant connection disabling access to "tenants" table
$resolver->reconnectTenantConnection();

如果您想使用自定义模型,注册一个自定义服务提供者,将单例绑定到TenantContract,并解析到您的自定义租户模型实例。只要在加载EnvTenant\TenantServiceProvider之前加载您的服务提供者,EnvTenant将自动回退到您的自定义模型。

在您的app/Providers文件夹中创建此示例服务提供者CustomTenantServiceProvider.php

<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Tenant;

class CustomTenantServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->app->singleton('TenantContract', function()
        {
            return new Tenant();
        });
    }

    public function register()
    {
        //
    }
}

然后在config/app.php文件中注册App\Providers\CustomTenantServiceProvider::class

事件

在整个生命周期中会触发事件,允许您监听和自定义行为。

租户激活

ThinkSayDo\EnvTenant\Events\TenantActivatedEvent

租户解析

ThinkSayDo\EnvTenant\Events\TenantResolvedEvent

租户未解析

ThinkSayDo\EnvTenant\Events\TenantNotResolvedEvent

租户未通过Web解析,将抛出异常

ThinkSayDo\EnvTenant\Events\TenantNotResolvedException

会话安全

Laravel中的会话可以被锁定到域名,防止用户在域名间跳转,并可能保留其身份验证。以下是一些可能有用的快速示例代码。我相信还有更复杂的处理方式。将来,我也可能在EnvTenant中添加一些跨域安全。

在您的会话配置文件中,将域名值改为类似以下内容

'domain' => ( ! empty($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : null,

享受!报告问题或建议。