第八章总结与问题梳理

8.1多角色用户权限

本节教程使用了一种普遍的角色+权限的后台权限管理模式,安装扩展包叫做laravel-permission。我以前是做CMS系统的,所以对这种模式很熟悉,只是这里多了一层关于模型的判断,而非以前我建个role_user表直接让user_id 与 role_id的进行关联,本教程只有user模型,虽然没接触过其他模型的例子,但扩展性更强是毋庸置疑的了。

在这里具体分析一下各个表,梳理一下

1.roles 角色模型表

第八章总结与问题梳理

很容易理解,不多解释。关于guard_name字段“守卫”的功能参看laravel-permission使用多个守卫( guard ) ,多了一层命名空间的判断。
2.permissions 权限模型表

第八章总结与问题梳理
同上,也很容易理解

3.model_has_roles模型与角色的关联表

第八章总结与问题梳理
这里类似于我过去建立的role_user表,现在变成了和model绑定,user_model的id就相当于过去的user_id,也算容易理解。

$user = App\Models\User::find(2);
$user->assignRole('writer', 'admin');

就是向这个表内的user模型对应的id=2绑定role_id数据。

4.role_has_permissions角色拥有的权限关联表

第八章总结与问题梳理
不难理解。
5.model_has_permissions 模型与权限关联表

第八章总结与问题梳理
这张表应该是直接赋予某个用户权限的表,因为教程里没有直接给用户授权的逻辑,因此这里是空的。

8.2站点权限部署

本节要解决两个需求

  • 拥有manage_contents权限的用户允许管理站点内所有话题和回复,包括编辑和删除动作;
  • Horizon 的控制面板,只有站长才有权限查看。

这里涉及到了授权策略,这个在之前的教程章节中学习过如何建立某个特定模型的授权策略,我们将创建的策略都建立在App\Policies目录中,并在App\Providers\AuthServiceProvider中注册。

授权策略涉及了服务容器和服务提供者相关的概念,说实话,我是在最近才接触到这些概念,每次看手册这块内容时脑袋里都是一团浆糊,现在是2020年8月15日,等我以后彻底弄明白了,会写一篇文章总结自己的收获,并在此留下文章链接。现在暂时还是很懵懂。

先顺着刚才的话,解决

  • Horizon 的控制面板,只有站长才有权限查看。

    class AuthServiceProvider extends ServiceProvider
    {
      /**
       * 应用程序的策略映射。
       *
       * @var array
       */
      protected $policies = [
          \App\Models\Reply::class => \App\Policies\ReplyPolicy::class,
           \App\Models\Topic::class => \App\Policies\TopicPolicy::class,
      ];
    
      /**
       * 注册任何应用程序 authentication / authorization 服务。
       *
       * @return void
       */
      public function boot()
      {
          $this->registerPolicies();
    
          // 修改策略自动发现的逻辑
          Gate::guessPolicyNamesUsing(function ($modelClass) {
              // 动态返回模型对应的策略名称,如:// 'App\Model\User' => 'App\Policies\UserPolicy',
              return 'App\Policies\\'.class_basename($modelClass).'Policy';
          });
    
          \Horizon::auth(function($request){
              //是否登录
              if(\Auth::check()){
                  //是否是站长
                  return \Auth::user()->hasRole('Founder');
              }else{
                  return false;
              }
          });
      }
    }

    针对上面的代码梳理一下,首先我们$policies中添加了需要注册的策略映射关系,在boot方法中,用registerPolicies()方法调用Gate对进行注册。此前我们修改了策略自动发现的逻辑。
    下面对\horizon路由进行访问权限的设定,方法是调用\Horizon模型的auth方法接收一个回调函数返回的结果。

    还没有彻底明白这里为什么这样写,因为与之前的策略注册方式不同,希望以后能明白吧。

另一个需求是

  • 拥有manage_contents权限的用户允许管理站点内所有话题和回复,包括编辑和删除动作;
<?php

namespace App\Policies;

use Illuminate\Auth\Access\HandlesAuthorization;

class Policy
{
    use HandlesAuthorization;

    public function before($user, $ability)
    {
        // 如果用户拥有管理内容的权限的话,即授权通过
        if ($user->can('manage_contents')) {
            return true;
        }
    }
}

我们将使用授权策略的策略过滤器机制来实现统一授权的目的

手册原文:
before 方法将在策略上的任何其他方法之前执行,从而使您有机会在实际调用预期的策略方法之前授权操作。此功能最常用于授权应用程序管理员执行任何操作

也就是说这个before方法可以在任何一个策略中使用,而我们这里在Policy中使用,就相当于在所有继承Policy的策略中使用。

8.3-8.7都是在围绕Laravel Administrator 这款扩展

教程中介绍了administrator的配置选项,以及配合使用扩展所要做的一些修改,值得注意的知识点有:

  • Eloquent 修改器

这里是为了处理密码保存时,进行加密的操作,以及头像保存目录的添加,详见 8.4管理后台-修改用户密码

  • 创建模型链接的辅助方法

能够通过Eloquent数据模型获得跳转链接,详见8.6后台管理-话题模型配置

  • 防范XSS攻击

由于后台没有blade模板进行转义,administrator中output输出的HTML内容使用了Laravel自带的e()函数进行转义。此处我不太明白,之前发帖功能里面需要用HTMLPurifier for Laravel扩展和这里的e()函数作用是否是相同的。

  • 站点配置中清空缓存操作
<?php

return [
·
·
·

    // 你可以自定义多个动作,每一个动作为设置页面底部的『其他操作』区块
    'actions' => [

        // 清空缓存
        'clear_cache' => [
            'title' => '更新系统缓存',

            // 不同状态时页面的提醒
            'messages' => [
                'active' => '正在清空缓存...',
                'success' => '缓存已清空!',
                'error' => '清空缓存时出错!',
            ],

            // 动作执行代码,注意你可以通过修改 $data 参数更改配置信息
            'action' => function(&$data)
            {
                \Artisan::call('cache:clear');
                return true;
            }
        ],
    ],
];

我目前的程序中,执行php artisan cache:clear时会报错

Failed to clear cache. Make sure you have the appropriate permissions.

不知道为什么会导致这个原因。
然而这里的

\Artisan::call('cache:clear'); 

却可以执行。也算我目前的一个未解之谜。

8.8后台访问权限

本节不难理解
值得我个人注意的是,对于闭包函数的调用问题

    /*
     * 权限控制的回调函数。
     *
     * 此回调函数需要返回 true 或 false ,用来检测当前用户是否有权限访问后台。
     * `true` 为通过,`false` 会将页面重定向到 `login_path` 选项定义的 URL 中。
     */
    'permission' => function () {
        // 只要是能管理内容的用户,就允许访问后台
        return Auth::check() && Auth::user()->can('manage_contents');
    },

下面是在控制器中调用上面的函数(错误演示)

        if(config('administrator.permission')){

            return redirect(url(config('administrator.uri')),302);
        }

注意到了吗?我这里忘记加()了,调用闭包函数要在后面加括号。

        if(config('administrator.permission')()){

            return redirect(url(config('administrator.uri')),302);
        }
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

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