这两课的总结

总结

  1. 两个包的使用

    • laravel_permission => 用于权限管理
      • 安装命令 composer require "spatie/laravel-permission:~2.7"
      • 安装完成后不能直接用,还需要 php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations" 这段命令生成迁移文件,然后执行 php artisan migrate 进行文件迁移(创建5张数据表:权限表,角色表,权限角色关系表,角色用户关系表,权限用户关系表)
      • 生成配置文件用命令 php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config" => config/permisson.php
    • sudosu => 用于在本地开发环境下解决需要频繁更改用户测试权限时需要不停地手动输入账号密码登陆登出的问题(装上可以一键换当前用户)

      • 安装命令 composer require "viacreative/sudo-su:~1.1"
      • 注册服务 app/Providers/AppServiceProvider@register
        public function register()
        {
        if (app()->isLocal()) {
            $this->app->register(\VIACreative\SudoSu\ServiceProvider::class);
        }
        }

        app()->isLocal() => 读的就是 .env 中的 APP_ENV=local 的值,当是 local 的时候,就说明项目跑在本地开发环境。这个函数就是说:当项目处于本地开发环境下的时候,注册 sudosu 插件提供的服务。

      • 发布资源文件 php artisan vendor:publish --provider="VIACreative\SudoSu\ServiceProvider" ,然后编辑生成的配置文件 config/sudosu.php
        
        <?php

      return [
      // 允许使用的顶级域名
      'allowed_tlds' => ['dev', 'local', 'test'],

      // 用户模型
      'user_model' => App\Models\User::class

      ];

      > 数组第一项目 'allowed_tlds' 就是判断网站的网址,如果是 .dev .local .test 结尾则可以访问插件
      
      > 第二项就是指定用户模型
      
      * 在布局模板上导入按钮 

      @if (app()->isLocal())
      @include('sudosu::user-selector')
      @endif

      
      > 现在就可以看得到那个切换用户的小按钮了。

使用 laravel_permission 权限认证的开发逻辑:

  • 开发逻辑和前面的权限管理:

    1. 确定角色:确定我们开发的应用中有哪些角色,比如这次的论坛项目有角色:游客,普通用户,管理员,站长。
    2. 在开发过程中,我们通过中间件 auth 已经搞定了 【游客 => 普通用户,管理员,站长(这3个都是已登陆用户)】之间的权限管理:
      // 举例,在禁止游客访问的控制器中:
      public function __construct()
      {
      $this->middleware('auth');
      }
    3. 接着就是已登陆用户之间的权限管理,我们通过 TopicPolicy 和 ReplyPolice 也搞定了:写了一些方法进行判断,比如
      
      # TopicPolicy@destroy => 进行判断:当前用户是否是发帖的人(普通用户只能删自己发的帖子)
      public function destroy(User $user, Topic $topic)
      {
      return $user->isAuthorOf($topic);
      }

    然后在控制层,用下面的代码进行授权

    $this->authorize('destroy', $topic);

    或者在视图层,用下面的代码对删除按钮进行显示和隐藏(判断渲染与否)

    @can('destroy', $topic)
    @endcan

  • 今天做的权限管理:

    1. laravel_permission 安装好了之后,生成迁移文件,然后跑迁移:这一过程让我们创建了5张数据表,分为是
      • 权限表 -> 配置权限名称,比如 manage_contents (管理内容)
      • 角色表 -> 配置角色名称,比如 Founder (站长)
      • 权限角色关系表 -> 这张表存储角色和权限的关系,一个角色有多个关系,比如 Founder 站长有所有权限。
      • 角色用户关系表 -> 这张表存储用户和角色的关系,一个用户有多个角色,比如1号用户可以扮演 Founder。
      • 权限用户关系表 -> 这张表存储权限和用户的关系,即跳过上一张表,直接给用户权限而不是给用户角色。
    2. 为了让整个项目开发和部署起来很方便,做下面的事

      • 在 User 模型中引用 trait(等会要用 trait 提供的一些方法)
        
        use Spatie\Permission\Traits\HasRoles;

      ...

      use HasRoles;
      * 溜一个迁移文件 `php artisan make:migration seed_roles_and_permissions_data` :创建默认的权限、角色、并且给角色赋予权限

      // 这里是 laravel_permission 扩展提供的两个模型文件
      use Spatie\Permission\Models\Role;
      use Spatie\Permission\Models\Permission;

      // up()
          // 清除缓存
          app()['cache']->forget('spatie.permission.cache');
      
          // 创建权限 Persisson::create(['name' => '权限名'])
          Permission::create(['name' => 'manage_contents']);
          Permission::create(['name' => 'manage_users']);
          Permission::create(['name' => 'edit_settings']);
      
          // 创建角色 Role::create(['name' => '角色名'])
          $founder = Role::create(['name' => 'Founder']); //站长
          // 赋予权限 $角色->givePermessionTo('权限名')
          $founder->givePermissionTo('manage_contents');
          $founder->givePermissionTo('manage_users');
          $founder->givePermissionTo('edit_settings');
      
          // 创建管理员角色
          $maintainer = Role::create(['name' => 'Maintainer']);
          $maintainer->givePermissionTo('manage_contents');
      
      // down()
          // 清除缓存
          app()['cache']->forget('spatie.permission.cache');
      
          // 清空所有数据表数据
          $tableNames = config('permission.table_names'); //这一步应该是读取数据表名前缀配置项
          Model::unguard(); //记得解除模型保护
          DB::table($tableNames['role_has_permissions'])->delete(); // 扩展包的数据表名都叫做 $前缀['数据表名']
          DB::table($tableNames['model_has_roles'])->delete();
          DB::table($tableNames['model_has_permissions'])->delete();
          DB::table($tableNames['roles'])->delete();
          DB::table($tableNames['permissions'])->delete();
          Model::reguard(); //最后重新开启模型保护
      * 给1号用户(我们开发中一直以来的假定的管理员)Founder 角色,给2号用户(方便我们等下测试)管理员角色。在 UsersTableSeeder 中实现

      // 配置用户
      $user = User::find(1);

      //... 这一部分是我们设置用户的用户名、密码等。

      // 配置权限 $user->assignRole('角色')
      $user->assignRole('Founder');

      $user = User::find(2); //重新找2号用户存当前 user
      $user->assignRole('Maintainer'); //给普通管理员角色

    3. 接着前面的逻辑,我们已经写了两个授权策略文件(TopicPolicy 和 ReplyPolicy),这两个文件都是用于:判断当前用户是不是帖子或者回复的作者,只有是帖子或者回复的作者时,才可以删帖、编辑帖、删除回复。接下来,我们想让拥有权限 manage_contents 的用户,有删除、编辑其他用户的帖子,以及删除其他人的回复的功能。

      这里就用了一个小技巧:直接写 Policy@before 方法:Policy 类作为其他(除了 UserPolicy 外) Policy 的基类(被继承),它提供一个 bofore 方法,当这个方法返回真的时候,直接就授权了,当返回假的时候,才去调用指定的授权认证。

      public function before($user, $ability)
      {
      if ($user->can('manage_contents')) {
      return true;
      }
      }
    4. horizon 只有 Founder 可以方法,需要在 app/Provider/AuthServiceProvider@boot 中声明(这里最好背下来)

      public function boot()
      {
      $this->registerPolicies();
      
      \Horizon::auth(function ($request) {
          // 是否是站长
          return \Auth::user()->hasRole('Founder');
      });
      }
  • 权限管理的常用方法

    1. 创建权限
      
      use Spatie\Permission\Models\Permission; //确保引用 Permission 模型

    ...

    Permission::craete(['name' => '权限名']); //只用给 name 赋值
    2. 创建角色并授权

    use Spatie\Permission\Models\Role; //确保引用 Role 模型

    ...

    $role = Role::create(['name' => '角色名']); //同样只用给 name 赋值,返回的就是当前创建的角色
    $role->givePermissionTo('权限名'); //给角色赋予指定权限
    3. 给用户一个角色

    确保 User 模型引用 trait HasRoles 。

    use Spatie\Permission\Traits\HasRoles;

    class User extends Authenticatable
    {
    use HasRoles;
    }

    在需要的地方

    $user->assignRole('角色名');

    4. 判断用户是否有权限

    $user->can('权限名');

    5. 判断用户是否是某个角色

    $user->hasRole('角色名');

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 2

发现本站格式化 md 的那个插件可能有问题,在本机上可以正常显示,但是在这里就不行了。
如果有需要参考的朋友可以来 我的 github 笔记本 上我的笔记。

5年前 评论

不知道为什么, 我项目加载很慢, 我也配置了加载速度问题, 现在还是很慢, 前面都很快, 可是到了 列队那一章的时候就变慢了。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!