我在寻找某种逻辑来限制用户访问同一模型内内容的过程中处于困境。例如,供应商只能看到他们提供的产品,而客户只能看到他们购买的产品。 (注意:每个产品可以有多个供应商或客户。我们将id称为产品节点)
现在,我已将一个产品关系设为多个供应商,而一个产品则属于多个客户。
目前,我在自己的网站上拥有Spatie角色和权限,这非常适合1个租户(主要是我们办公室(50-150个用户))。如果我们的办公室用户可以看到多个客户或产品的详细信息,这不是问题,但是当客户登录时问题就开始了。我只想显示产品价格或属于他们的数据。查看其他客户或供应商数据非常重要。
我看过多租户实施,但是我认为这不能满足我的需求。
如果您忽略了某些内容,我深表歉意,但我会尽力确保数据的安全。
您能否阐明这一困境,并把我引向正确的道路?
非常感谢您的输入!
我假设您要限制的所有模型都与客户直接相关,因此您实际上可以添加一个全局范围,该范围将默认参数添加到查询中。
采用以下范围:
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Facades\Auth;
class CustomerOwnedScope implements Scope {
public function apply(Builder $builder, Model $model) {
if (Auth::guard('customer')->check()) {
$builder->where('customer_id', '=', Auth::guard('customer')->id);
}
}
public function extend(Builder $builder) {
$this->addWithoutCustomer($builder);
}
protected function addWithoutCustomer(Builder $builder) {
$builder->macro('withoutCustomer', function (Builder $builder) {
return $builder->withoutGlobalScope($this);
});
}
}
具有此范围的任何模型都将自动添加子句WHERE customer_id = ?
,其中?
是当前已认证客户的ID(如果已认证)。假设您使用的是Laravel身份验证,这将使您不必做任何特定的事情即可实现自己的目标。
它还会添加范围withoutCustomer()
,这将阻止添加where子句。
将其添加到属于客户的模型中的最简单方法是像这样创建自己的特征(关注):
<?php
namespace App\Concerns;
use App\Scopes\CustomerOwnedScope;
trait OwnedByCustomer {
public static function bootOwnedByCustomer() {
static::addGlobalScope(new CustomerOwnedScope);
}
public function customer() {
$this->belongsTo(Customer::class, 'customer_id');
}
}
这将添加客户关系,并添加范围以根据当前客户自动查询。
您显然可以对此进行进一步修改以包括其他关系,或者可以添加更多条件以仅适用于设置了特定标志或未设置标志(对于内部用户等)的客户。
整个方法确实假设您的内部管理员用户和外部客户用户使用不同的身份验证保护(在这种情况下,这是理想的方法。)>
我应该补充一点,上面的代码摘自我写的关于多租户主题的文章,特别是有关在单个数据库中处理租户的部分。如果您愿意,可以在这里阅读:https://ollieread.com/articles/laravel-multi-tenancy-avoiding-over-engineering#single-database