Laravel的大门和政策

今天,我们将讨论Laravel Web框架的授权系统。 Laravel框架以门和策略的形式实现授权。 在介绍了门和策略之后,我将通过实现一个自定义示例来演示概念。

我认为您已经了解了内置的Laravel身份验证系统,因为这对于理解授权概念至关重要。 显然,授权系统与身份验证系统协同工作,以标识合法的用户会话。

如果您不了解Laravel身份验证系统,我强烈建议您阅读官方文档 ,它为您提供了有关该主题的动手知识。

Laravel的授权方式

到目前为止,您应该已经知道Laravel授权系统具有两种形式-门和策略。 尽管这听起来可能很复杂,但是我想说,一旦掌握了它,就很容易实现它!

Gates使您可以使用基于封闭的简单方法来定义授权规则。 换句话说,当您想要授权与任何特定模型都不相关的动作时,门是实现该逻辑的理想场所。

让我们快速看一下基于门的授权的外观:

...
...
Gate::define('update-post', function ($user, $post) {
  return $user->id == $post->user_id;
});
...
...

上面的代码段定义了可以在应用程序中的任何位置调用的授权规则update-post

另一方面,要对任何模型的授权逻辑进行分组时,应使用策略。 例如,假设您的应用程序中有一个Post模型,并且您想授权该模型的CRUD操作。 在这种情况下,这就是您需要实施的策略。

class PostPolicy
{
  public function view(User $user, Post $post) {}
  public function create(User $user) {}
  public function update(User $user, Post $post) {}
  public function delete(User $user, Post $post) {}
}

如您所见,这是一个非常简单的策略类,它定义了Post模型的CRUD操作的授权。

因此,这是Laravel中的闸门和政策的简介。 从下一部分开始,我们将对每个元素进行实际演示。

盖茨

在本节中,我们将看到一个真实的例子来理解门的概念。

通常,当您需要注册组件或服务时,最终还是要看Laravel服务提供商。 遵循该约定,让我们继续在app/Providers/AuthServiceProvider.php定义我们的自定义门,如以下代码片段所示。

<?php
namespace App\Providers;

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

class AuthServiceProvider extends ServiceProvider
{
  /**
   * The policy mappings for the application.
   *
   * @var array
   */
  protected $policies = [
    'App\Model' => 'App\Policies\ModelPolicy',
  ];

  /**
   * Register any authentication / authorization services.
   *
   * @return void
   */
  public function boot()
  {
    $this->registerPolicies();
    
    Gate::define('update-post', function ($user, $post) {
      return $user->id == $post->user_id;
    });
  }
}

boot方法中,我们定义了自定义门:

Gate::define('update-post', function ($user, $post) {
  return $user->id == $post->user_id;
});

在定义门时,它会根据闭门定义中定义的授权逻辑,采用闭包返回TRUE或FALSE的方式。 除了闭包功能外,还有其他定义门的方法。

例如,以下门定义调用控制器动作而不是闭合函数。

Gate::define('update-post', 'ControllerName@MethodName');

现在,让我们继续并添加自定义路由,以便我们可以演示基于门的授权如何工作。 在路由文件routes/web.php ,添加以下路由。

Route::get('service/post/gate', 'PostController@gate');

我们也创建一个关联的控制器文件app/Http/Controllers/PostController.php

<?php
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Post;
use Illuminate\Support\Facades\Gate;

class PostController extends Controller
{
  /* Make sure you don't user Gate and Policy altogether for the same Model/Resource */
  public function gate()
  {
    $post = Post::find(1);

    if (Gate::allows('update-post', $post)) {
      echo 'Allowed';
    } else {
      echo 'Not Allowed';
    }
    
    exit;
  }
}

在大多数情况下,你会最终使用要么allowsdenies的方法Gate门面授权某个动作。 在上面的示例中,我们使用了allows方法来检查当前用户是否能够执行update-post操作。

眼睛敏锐的用户会注意到,我们仅将第二个参数$post传递给了闭包。 第一个参数是当前登录的用户,由Gate门面自动注入。

因此,这就是您应该使用Gates授权Laravel应用程序中的操作的方式。 下一部分将讨论如何使用策略,如果您希望对模型实施授权。

政策规定

正如我们前面所讨论的,当您想要对任何特定模型或资源进行逻辑上的授权操作分组时,这就是您要寻找的策略。

在本节中,我们将为Post模型创建一个策略,该策略将用于授权所有CRUD操作。 我假设您已经在应用程序中实现了Post模型; 否则,类似的事情将会发生。

在创建存根代码时,Laravel artisan命令是您最好的朋友。 您可以使用以下artisan命令为Post模型创建策略。

$php artisan make:policy PostPolicy --model=Post

如您所见,我们提供了--model=Post参数,以便它创建所有CRUD方法。 如果没有,它将创建一个空白的Policy类。 您可以在app/Policies/PostPolicy.php找到新创建的Policy类。

让我们用以下代码替换它。

<?php
namespace App\Policies;

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

class PostPolicy
{
  use HandlesAuthorization;

  /**
   * Determine whether the user can view the post.
   *
   * @param  \App\User  $user
   * @param  \App\Post  $post
   * @return mixed
   */
  public function view(User $user, Post $post)
  {
    return TRUE;
  }

  /**
   * Determine whether the user can create posts.
   *
   * @param  \App\User  $user
   * @return mixed
   */
  public function create(User $user)
  {
    return $user->id > 0;
  }

  /**
   * Determine whether the user can update the post.
   *
   * @param  \App\User  $user
   * @param  \App\Post  $post
   * @return mixed
   */
  public function update(User $user, Post $post)
  {
    return $user->id == $post->user_id;
  }

  /**
   * Determine whether the user can delete the post.
   *
   * @param  \App\User  $user
   * @param  \App\Post  $post
   * @return mixed
   */
  public function delete(User $user, Post $post)
  {
    return $user->id == $post->user_id;
  }
}

为了能够使用我们的Policy类,我们需要使用Laravel服务提供商注册它,如以下代码片段所示。

<?php
namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use App\Post;
use App\Policies\PostPolicy;

class AuthServiceProvider extends ServiceProvider
{
  /**
   * The policy mappings for the application.
   *
   * @var array
   */
  protected $policies = [
    'App\Model' => 'App\Policies\ModelPolicy',
    Post::class => PostPolicy::class
  ];

  /**
   * Register any authentication / authorization services.
   *
   * @return void
   */
  public function boot()
  {
    $this->registerPolicies();
  }
}

我们已经在$policies属性中添加了Policy的映射。 它告诉Laravel调用相应的策略方法来授权CRUD操作。

您还需要使用registerPolicies方法注册策略,就像在boot方法中所做的那样。

进一步讲,让我们在routes/web.php文件中创建几个自定义路由,以便我们可以在那里测试Policy方法。

Route::get('service/post/view', 'PostController@view');
Route::get('service/post/create', 'PostController@create');
Route::get('service/post/update', 'PostController@update');
Route::get('service/post/delete', 'PostController@delete');

最后,让我们在app/Http/Controllers/PostController.php创建一个关联的控制器。

<?php
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Post;
use Illuminate\Support\Facades\Auth;

class PostController extends Controller
{
  public function view()
  {
    // get current logged in user
    $user = Auth::user();
    
    // load post
    $post = Post::find(1);
    
    if ($user->can('view', $post)) {
      echo "Current logged in user is allowed to update the Post: {$post->id}";
    } else {
      echo 'Not Authorized.';
    }
  }

  public function create()
  {
    // get current logged in user
    $user = Auth::user();

    if ($user->can('create', Post::class)) {
      echo 'Current logged in user is allowed to create new posts.';
    } else {
      echo 'Not Authorized';
    }

    exit;
  }

  public function update()
  {
    // get current logged in user
    $user = Auth::user();

    // load post
    $post = Post::find(1);

    if ($user->can('update', $post)) {
      echo "Current logged in user is allowed to update the Post: {$post->id}";
    } else {
      echo 'Not Authorized.';
    }
  }

  public function delete()
  {
    // get current logged in user
    $user = Auth::user();
    
    // load post
    $post = Post::find(1);
    
    if ($user->can('delete', $post)) {
      echo "Current logged in user is allowed to delete the Post: {$post->id}";
    } else {
      echo 'Not Authorized.';
    }
  }
}

您可以使用多种方法来使用策略授权操作。 在上面的示例中,我们使用了User模型来授权Post模型操作。

用户模型提供授权目的订立两个有用的方法cancantcan方法用于检查当前用户是否能够执行特定操作。 和的对应物can的方法,所述cant的方法,被用于确定该动作执行的无力。

让我们从控制器中获取view方法的代码片段,以view其确切功能。

public function view()
{
  // get current logged in user
  $user = Auth::user();
  
  // load post
  $post = Post::find(1);
  
  if ($user->can('view', $post)) {
    echo "Current logged in user is allowed to update the Post: {$post->id}";
  } else {
    echo 'Not Authorized.';
  }
}

首先,我们加载当前登录的用户,这为我们提供了User模型的对象。 接下来,我们使用Post模型加载示例帖子。

向前,我们已经使用了User模型的can方法来授权Post模型的view动作。 can方法的第一个参数是您要授权的操作名称,第二个参数是您要针对其授权的模型对象。

这说明了如何使用User模型通过策略授权操作。 另外,如果您在授权某个操作的同时处于控制器中,则也可以使用Controller Helper

…
$this->authorize('view', $post);
…

如您所见,如果使用Controller Helper,则不需要加载User模型。

这就是您可以使用的策略的概念,并且在授权模型或资源时非常方便,因为它允许您将授权逻辑集中在一个位置。

只要确保您对模型的相同操作完全不使用门和策略,否则会造成问题。 今天就从我这边开始,我将其称为一天!

结论

今天,正是Laravel授权在我的文章中占据了中心位置。 在本文的开头,我介绍了Laravel授权的主要元素,闸门和策略。

之后,我们经历了创建自定义门和策略的过程,以了解其在现实世界中的工作方式。 我希望您喜欢这篇文章,并从Laravel的背景中学到了一些有用的东西。

对于那些刚刚开始使用Laravel或希望通过扩展来扩展您的知识,网站或应用程序的人,我们可以在Envato Market上进行各种研究。

与往常一样,我很乐意使用以下供稿以评论的形式收到您的来信!

翻译自: https://code.tutsplus.com/tutorials/gates-and-policies-in-laravel--cms-29780

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值