可选功能
# 可选功能
"Features"是提供核心租户逻辑不需要的附加功能的类。 开箱即用,该包装具有以下功能:
用户模拟
用于从其他上下文为租户数据库的用户生成模拟令牌Telescope标签
用于将带有当前租户 ID 的标签添加到 Telescope 条目租户配置
用于将键从租户存储映射到应用程序配置跨域名重定向
用于在RedirectResponse
上添加domain()
宏,让您更改生成路由的预期主机名通用路由
用于在中央和租户上下文中工作的路由操作所有包的功能都在`Stancl\Tenancy\ 功能命名空间。
您可以通过将类名添加到tenancy.features
配置来注册功能。
# 用户模拟
该扩展包附带了一项功能,可让您模拟租户数据库中的用户。 此功能适用于任何识别方法和任何身份验证保护 - 即使您使用多个。
# 它是如何工作的
您生成一个模拟令牌并将其存储在中央数据库的 tenant_user_impersonation_tokens
表中。
表中的每条记录都包含以下数据:
- 令牌值(128 个字符串)
- 租户ID
- 用户ID
- 授权保护的名称
- 模拟发生后重定向到的 URL
你访问你创建的模拟路由——尽管你这边需要做的工作很少,但你的路由主要会调用该功能提供的方法。 此路由是 租户路由,这意味着如果使用域标识,则它位于租户域上,如果使用路径标识,则它以租户 ID 为前缀。
此路由检查尝试根据令牌在该表中查找记录,如果它有效,它将使用存储的用户 id 对您进行身份验证,并将您重定向到存储的 URL。
如果模拟成功,则从数据库中删除令牌。
默认情况下,所有令牌都会在 60 秒后过期,并且可以自定义此 TTL — 请参阅最底部的部分。
# 启用该功能
要启用此功能,请转到您的 config/tenancy.php
文件并确保以下类在配置的 features
部分中:
Stancl\Tenancy\Features\UserImpersonation::class,
接下来,发布使用模拟令牌创建表的迁移:
php artisan vendor:publish --tag=impersonation-migrations
最后,运行迁移:
php artisan migrate
# 用法
首先,您需要创建一个如下所示的租户路由:
use Stancl\Tenancy\Features\UserImpersonation;
// We're in your tenant routes!
Route::get('/impersonate/{token}', function ($token) {
return UserImpersonation::makeResponse($token);
});
// Of course use a controller in a production app and not a Closure route.
// Closure routes cannot be cached.
请注意,路线路径或名称完全由您决定。 该程序包执行的唯一逻辑是生成令牌、验证令牌和模拟用户登录。
然后,要在您的应用程序中使用模拟,请生成如下令牌:
// Let's say we want to be redirected to the dashboard
// after we're logged in as the impersonated user.
$redirectUrl = '/dashboard';
$token = tenancy()->impersonate($tenant, $user->id, $redirectUrl);
并将用户(或者,大概是“管理员”)重定向到您创建的路由。
# 域名识别
// 注意:这不是包的一部分,由你来实现
// 如果您需要“主域名”的概念。 或者也许你使用
// 每个租户一个域名。 该软件包可让您做任何想做的事情。
$domain = $tenant->primary_domain;
return redirect("https://$domain/impersonate/{$token->token}");
# 路径识别
// 确保你为你的路由使用正确的前缀。
return redirect("{$tenant->id}/impersonate/{$token->token}");
就这样了。用户将被重定向到你的模拟路由,以被模拟的用户身份登录,最后被重定向到你的重定向URL。
# 自定义身份验证保护
如果您使用多个身份验证保护,您可能需要指定模拟逻辑应使用的身份验证保护。
为此,只需将身份验证保护名称作为第四个参数传递给 impersonate()
方法。 所以扩展我们上面的例子:
tenancy()->impersonate($tenant, $user->id, $redirectUrl, 'jwt');
# 定制化
您可以通过将以下静态属性设置为要使用的秒数来自定义模拟令牌的 TTL:
Stancl\Tenancy\Features\UserImpersonation::$ttl = 120; // 2分钟
# Telescope 标签
TODO
# 租户配置
您可能需要在应用程序中使用特定于租户的配置。 该配置可以是 API 密钥,例如“每页产品数”和许多其他内容。
您可以只使用租户模型来获取这些值,但您可能仍想使用 Laravel 的config()
,因为::
- 关注点分离——如果你只编写与租户实现无关的
config('shop.products_per_page')
,你将有更好的时间改变租户实现 - 默认值——您可能只想使用租户存储来覆盖配置文件中的值
# 启用该功能
在您的 tenancy.features
配置中取消注释以下行:
// Stancl\Tenancy\Features\TenantConfig::class,
# 配置映射
此功能根据$storageToConfigMap
静态属性 将租户存储中的键映射到配置键。
例如,如果您的 $storageToConfigMap
看起来像这样:
\Stancl\Tenancy\Features\TenantConfig::$storageToConfigMap = [
'paypal_api_key' => 'services.paypal.api_key',
],
当租户初始化时,租户模型中paypal_api_key
的值将被复制到services.paypal.api_key
配置。
# 将值映射到多个配置键
有时您可能希望将值复制到多个配置键。 为此,请将配置键指定为数组:
\Stancl\Tenancy\Features\TenantConfig::$storageToConfigMap = [
'locale' => [
'app.locale',
'locales.default',
],
],
# 跨域重定向
要启用此功能,请在您的 tenancy.features
配置中取消注释 Stancl\Tenancy\Features\CrossDomainRedirect::class
行。
有时您可能希望将用户重定向到不同域名(而不是当前域名)上的特定路由。 假设您想在租户注册后将其重定向到其域上的home
路径:
return redirect()->route('home')->domain($domain);
您还可以使用 tenant_route()
助手将用户重定向到另一个域。
return redirect(tenant_route($domain, 'home'));
# 通用路由
注意:如果你需要自定义onFail逻辑,你不能使用这个功能,因为它将覆盖你对该逻辑的任何修改。相反,请研究一下这个功能的源代码,让你的onFail逻辑也实现通用路由。如果你这样做,请确保在配置文件中禁用这个功能,然后再清除缓存。
有时,您可能希望在中央应用程序和租户应用程序中使用完全相同的路由操作。 请注意路线 action 的重点——您可以在中央和租户路线中使用相同的 path 和不同的动作,而本节涵盖使用相同的 route 和 action。
一般来说,尽量避免这些用例,宁愿重复代码。在中心和租户应用程序中为用户使用相同的控制器和模型,一旦你需要稍微不同的行为,就会出现问题--例如控制器返回的不同视图,模型中的不同行为,等等。
首先,通过在您的tenancy.features
配置中取消注释以下行来启用 UniversalRoutes
功能:
Stancl\Tenancy\Features\UniversalRoutes::class,
接下来,进入你的app/Http/Kernel.php
文件,添加以下中间件组:
'universal' => [],
我们将使用这个中间件组作为路由的一个 "标志",以标记它是一个通用路由。我们不需要组内的任何实际中间件。
然后,创建一个这样的路由:
Route::get('/foo', function () {
// ...
})->middleware(['universal', InitializeTenancyByDomain::class]);
而且该路线将在中央和租户应用程序中工作。如果找到一个租户,租户将被初始化。否则,将使用中央上下文。
如果你使用不同的中间件,看看UniversalRoutes
功能的源代码,并相应地改变公共静态属性。