多租户数据库的动态缓存前缀

问题描述 投票:0回答:1

我在一个多租户 Lumen 项目 (v8.3.4) 中工作,并使用这个 mostafamaklad/laravel-permission-mongodb (v3.1.0) 包来处理用户的角色权限。

我面临的问题是每个租户的角色和权限都由使用相同缓存键的包缓存。因此,如果租户被切换,那么角色和权限将从缓存中提供,并且不会进行基于租户的数据库调用。因此包总是返回错误。

我正在寻找一种方法来分别为每个租户添加缓存前缀。我尝试了一些方法,但没有成功。

到目前为止我尝试过的一些方法是:

  1. 使用租户 ID 将中间件添加到缓存键的前缀 => 它不起作用,因为包服务提供商甚至在执行中间件之前就注册了模型并获取了缓存。
  2. 在中间件中注册包服务提供商 => 它没有工作,因为包可能使用默认配置构建
  3. 当在
    ServiceProviders
    中设置缓存前缀时,包无法识别这些值并使用我猜的默认值

希望问题清楚,如果需要任何澄清,请告诉我。

提前致谢。

php laravel lumen
1个回答
0
投票

这里的问题是

Illuminate
命名空间中的提供程序将首先加载。您可以使用以下技巧解决此问题:

  1. CachePrefixServiceProvider
    中创建一个服务提供者(让我们称之为
    app\Providers
    )来为缓存添加租户ID前缀。将名称空间更改为
    Illuminate\MyProject
    之类的名称。服务提供商看起来像这样:
namespace Illuminate\MyProject;

/**
 * Class CachePrefixServiceProvider (incorrect namespace, hack to be loaded first)
 *
 * @package Illuminate\MyProject\CachePrefixServiceProvider
 */
class CachePrefixServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Take the tenant id from the header or somewhere else   
        $tenantId = request()->header('tenant-id');

        // In case of file cache    
        if (config('cache.default') === 'file') {
            config(
                 ['cache.stores.file.path' => storage_path('framework/cache/data/' . $tenantId)]
            );

            return;
        }

        // Will work in case of Redis / Memcached
        config(['cache.prefix' => $tenantId . '_cache']);
    }
}

当然您可以根据需要更改前缀。

  1. 你会得到一个错误,自动加载将失败,因为提供者不符合 PSR 标准。您可以通过将类添加到 composer.json 中的自动加载字段来解决此问题:
"autoload": {
    "files": [
        "app/Providers/CachePrefixServiceProvider.php"
    ],
...
}
  1. 将提供者添加到
    config/app.php
    中的提供者:
Illuminate\MyProject\CachePrefixServiceProvider::class,

不涉及此 hack 的任何其他解决方案将不胜感激。

© www.soinside.com 2019 - 2024. All rights reserved.