【问题标题】:Laravel permission cacheLaravel 权限缓存
【发布时间】:2019-07-25 12:50:11
【问题描述】:

我在 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-zahidhttps://stackoverflow.com/a/53511803/8487424 的方法,它可以很好地缓存permissions 表中的所有permisisons,但是有什么方法可以缓存所有权限以及特定用户和角色的权限当前登录的用户

【问题讨论】:

  • 如何缓存用户登录时的所有权限和角色,并在添加新记录时刷新缓存。 有几种方法:1)只是在会话中缓存它或 cookie,2) 使用 laravel cache 功能对其进行缓存,并在更新完成时清除缓存
  • 如果可用,请先用一些代码详细说明您的问题。
  • 这是我的完整代码Click here

标签: laravel


【解决方案1】:

您可以使用 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 需要更长的时间

【讨论】:

  • 我已经用要使用的代码示例更新了我的答案!
  • 我试过了,但我收到错误see here
  • 你忘记了 ;设置 userId 后
【解决方案2】:

您可以将缓存存储在服务提供商中。我只是分享我的方法

$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);
                });
            });

Laravel Documentation 上查找更多信息

【讨论】:

  • 嗨,Emitaz。这将获得所有权限,但不会获得当前用户的权限
  • 我只是分享了将数据存储在缓存中的概念,以后使用,您可以检查当前用户权限是否存在于$permissions数组中。
  • 现在我已经尝试过了,它缓存了权限表中所有可用的权限
  • 但是有没有办法缓存所有权限以及当前正在登录的特定用户或角色的权限
  • 当前记录的用户数据可以在 Auth::user() 中找到,并且它的所有数据都存储在会话中,所以每次你需要从用户表中获取任何数据时它不会执行另一个查询。
【解决方案3】:

我终于找到了解决方案。 Artisan 缓存清除命令无法正常工作。 尝试删除此文件夹上的缓存。 存储/框架/缓存/数据

这应该是肯定的。 祝你好运

【讨论】:

    猜你喜欢
    • 2021-11-18
    • 1970-01-01
    • 2013-06-10
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    相关资源
    最近更新 更多