我正在使用自己的实现来实现laravel中的用户角色和权限,如何在用户登录时缓存所有权限和角色,并在添加新记录时刷新缓存。 我的表是用户,角色,权限,permission_role,permission_user,role_user。这是我的表结构
我已经在提供程序上创建了该代码,并将此代码添加到了启动方法
Permission::get()->map(function ($permission)
{
Gate::define($permission->name, function ($user) use ($permission)
{
return $user->hasPermission($permission);
});
});
它工作正常,但是每次都在运行查询,这会使我的应用程序变慢,有没有办法缓存所有权限
这是我的PermissionServiceProvider类
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Blade;
use App\Models\Permission;
class PermissionServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
if (Schema::hasTable('permissions'))
{
Permission::get()->map(function ($permission)
{
Gate::define($permission->name, function ($user) use ($permission)
{
return $user->hasPermission($permission);
});
});
}
Blade::directive('role', function ($role)
{
return "<?php if(Auth::user()->hasRole({$role})): ?>";
});
Blade::directive('endrole', function ($role)
{
return "<?php endif; ?>";
});
}
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
}
最后进入用户模型
public function hasPermission($permission)
{
return $this->hasPermissionThroughRole($permission) || (bool) $this->permissions->where('name',$permission->name)->count();
}
public function hasPermissionThroughRole($permission)
{
foreach($permission->roles as $role)
{
if($this->roles->contains($role))
{
return true;
}
}
return false;
}
这也是我的小桶仓库
https://manojkiran@bitbucket.org/manojkiran/userrolesandpermissions.git
我已经尝试过@emtiaz-zahid
https://stackoverflow.com/a/53511803/8487424的方法可以很好地在permisisons
表中缓存所有permissions
的方法,但是有什么办法可以消除所有的渗透以及特定用户的权限和当前登录用户的角色
答案 0 :(得分:0)
您可以使用Laravel模型缓存,如以下链接所示:
https://laravel-news.com/laravel-model-caching
我将创建一种获取和缓存当前用户角色和权限的方法。
您可以在此处了解有关缓存的更多信息:
https://laravel.com/docs/5.7/cache
我希望这对您有帮助
更新
尝试这样的事情
if (Schema::hasTable('permissions') ) {
$userId = Auth::user()->id
return Cache::remember($this->cacheKey() . $userId . ':permissions', 60, function() use ($userId) {
return Permission::where('user_id', $userId)->get();
}
}
然后,您只需要更新hasPermission()
方法即可检查缓存。
也要避免使用map()
,因为php比sql花费更长的时间
答案 1 :(得分:0)
您可以将缓存存储在服务提供商中。我只是分享我的方法
$permissions = Cache::rememberForever('permissions', function () {
return Permission::get();
});
这将永久记住键名为permissions
的权限,直到您更改它为止
您还可以在特定时间记住这一点
$permissions = Cache::remember('permissions', 3600, function () {
return Permission::get();
});
我将其放置在应用服务提供商中,以便每次加载应用时都要检查是否在缓存中找到permissions
,然后不运行查询;如果找不到,则从数据库中获取该查询
因此您的脚本在缓存部分之后可能像这样:
$permissions->map(function ($permission)
{
Gate::define($permission->name, function ($user) use ($permission)
{
return $user->hasPermission($permission);
});
});
上找到更多信息
答案 2 :(得分:0)
最后我找到了解决方案。 Artisan cache clear命令无法正常运行。 尝试删除此文件夹上的缓存。 存储/框架/缓存/数据
这应该可以正常工作。 祝你好运