Laravel Policy 使用
10

Laravel 提供更简单的方式来处理用户授权动作。类似用户认证,有 2 种主要方式来实现用户授权:gates 和策略,我这里主要讲解下策略的使用。

文档 上面有详细的说明,我这里只根据自己使用过程做一个简单的笔记。

例子:我这里准备用编辑文章授权来做演示,在这个权限中,只有文章所有者可以编辑,来体验一下 Policy 如何实现它。

准备工作

安装 laravel

composer create-project --prefer-dist laravel/laravel laravel-vue "5.5.*"

建表

php artisan make:migration posts --create=posts

Schema::create('posts', function (Blueprint $table) {
  $table->increments('id');
  $table->string("title", 200);
  $table->text("content");
  $table->timestamps();
  $table->index('user_id');
});

创建 Model

php artisan make:model PostModel

# app/PostModel.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class PostModel extends Model
{
  protected $table = 'posts';
  protected $fillable = ['title', 'content', 'user_id'];
}

生成策略

策略其实就是授权方案所对应的类文件,它在 app/Policies 目录下面,下面我用命令创建一个策略文件。

php artisan make:policy PostPolicy

命令执行完毕之后,会生成 app/Policies/PostPolicy.php 文件,下面我们开始编辑它。

# app/Policies/PostPolicy.php
namespace App\Policies;

use App\User;
use App\PostModel;
use Illuminate\Auth\Access\HandlesAuthorization;

class TopicPolicy
{
  use HandlesAuthorization;

  public function create(User $user)
  {
    // code
  }

  public function update(User $user, PostModel $postModel)
  {
    return $user->id  === $postModel->user_id;
  }

  public function delete(User $user, PostModel $postModel)
  {
    // code
  }
}

注册策略

授权策略需要注册才能使用,在什么地方注册呢?laravel5.5AuthServiceProvider 中包含一个 policies 的属性,这里面注册策略,下面我们看下如何注册。

# app/Providers/AuthServiceProvider.php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

user App\PostModel;
use App\Policies\PostPolicy;

class AuthServiceProvider extends ServiceProvider
{
  protected $policies = [
    PostModel::class => PostPolicy::class,  // 注意在这里注册 policy
  ];

  public function boot()
  {
    $this->registerPolicies();
  }
}

使用策略

注册完毕之后,在 User 模型中有 cancant 方法来使用策略,如在 PostController 编辑时使用:

# app/Http/Controllers/PostController.php

public function create() {
  if (Auth::user()->can('create', PostModel)) { // 注意这里的用法
    // 可以创建
  } else {
    // 无权限
  }
}

public function update(Request $request) {
  $id = $request->input('id');
  $post = PostModel::findOrFail($id);
  if (Auth::user()->can('update', $post)) {
    // 可以编辑
  } else {
    // 无编辑权限
  }
}

如果你想超级管理员也拥有编辑权限的话,可以在定义策略的时候加上策略过滤器,也就是一个 before 方法:

# app/Policies/PostPolicy.php
public function before($user, $ability)
{
  if ($user->isSuperAdmin()) {
    return true;
  }
}

# app/User.php
public function isSuperAdmin()
{
  // 定义ID为1为超级管理员
  if ($this->id == 1) {
    return true;
  }
  return false;
}

balde 模板中使用 @can@cannot方法来判断

@can('create', App\PostModel::class)
  <a href="">创建</a>
@endcan

@can("update", $post)
  <a href="">编辑</a>
@endcan

好了,这次就写到这里,希望此篇笔记能帮助到你。

原文地址

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 1
Max

推荐使用
$this->authorize('update', $post);
不需要写多余的if else
对于不满足条件的情况,其会直接抛出一个403的异常

6个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!