Laravel のゲートと戦略

WBOY
WBOYオリジナル
2023-08-31 13:49:061544ブラウズ

Laravel のゲートと戦略

今日は、Laravel Web フレームワークの認可システムについて説明します。 Laravel フレームワークは、ゲートとポリシーの形式で認可を実装します。ゲートと戦略を紹介した後、カスタム例を実装して概念を説明します。

組み込みの Laravel 認証システムについては、承認の概念を理解するために必要なため、すでにご存知だと思います。明らかに、認可システムは認証システムと連携して、正当なユーザー セッションを識別します。

Laravel 認証システムについて知らない場合は、このトピックをより深く理解できる公式ドキュメントを読むことを強くお勧めします。

Laravelの認可方法

ここまでで、Laravel 認証システムにはゲートとポリシーという 2 つの種類があることをご存知でしょう。複雑なことのように聞こえるかもしれませんが、コツを掴めばとても簡単にできると思います。

Gate を使用すると、シンプルなクロージャベースのアプローチを使用して認可ルールを定義できます。言い換えれば、特定のモデルに関連付けられていない操作を承認したい場合、ゲートはそのロジックを実装するのに最適な場所です。

ゲートベースの認証がどのようなものかを簡単に見てみましょう:

リーリー

上記のコード スニペットは承認ルールを定義します。 update-post これはアプリケーションのどこからでも呼び出すことができます。

一方、任意のモデルの認可ロジックをグループ化する場合は、戦略を使用する必要があります。たとえば、アプリケーションに Post モデルがあり、そのモデルに対する CRUD 操作を承認するとします。この場合、これが実装する必要がある戦略です。

リーリー

ご覧のとおり、これは Post モデルでの CRUD 操作の承認を定義する非常に単純なポリシー クラスです。

これは、Laravel のゲートと戦略の紹介です。次のセクションから、各要素の実践的なデモを行っていきます。

###ドア###

このセクションでは、実際の例を通してドアの概念を理解します。

カスタムドアの作成方法

コンポーネントまたはサービスを登録する必要がある場合、通常は Laravel サービスプロバイダーを探します。この規則に従って、次のコード スニペットに示すように、

app/Providers/AuthServiceProvider.php

でカスタム ゲートを定義しましょう。 リーリー

boot

メソッドで、カスタム ドアを定義します: リーリー ゲートが定義されている場合、ゲート定義で定義されている認可ロジックに応じて、

TRUE

または FALSE を返すクロージャが必要です。クロージャ関数以外にもゲートを定義する方法はあります。 たとえば、次のゲート定義では、クロージャ関数の代わりにコントローラ アクションを呼び出します。

リーリー

カスタムゲートの使用方法

さて、カスタム ルートを追加して、ゲートベースの認証がどのように機能するかをデモできるようにしましょう。ルート ファイル

routes/web.php

に次のルートを追加します。 リーリー 関連するコントローラー ファイル

app/Http/Controllers/PostController.php

も作成しましょう。 リーリー ほとんどの場合、特定のアクションを承認するには、最終的に

allows

または denies メソッド (Gate ファサード) を使用することになります。上記の例では、allows メソッドを使用して、現在のユーザーが update-post 操作を実行できるかどうかを確認します。 鋭いユーザーは、2 番目のパラメーター

$post

のみをクロージャに渡していることに気づくでしょう。最初のパラメータは現在ログインしているユーザーで、Gate ファサードによって自動的に挿入されます。 これは、Laravel アプリケーションでのアクションを承認するためにゲートを使用する方法です。モデルに認可を実装する場合は、次のセクションでポリシーの使用方法について説明します。

###ポリシー###

前に説明したように、特定のモデルまたはリソースの認可操作を論理的にグループ化する場合、必要なのはポリシーです。

カスタム ポリシーの作成方法

このセクションでは、すべての CRUD 操作を承認する

Post

モデルのポリシーを作成します。アプリケーションに

Post

モデルをすでに実装していると仮定しますが、そうでない場合は、同様のものが使えます。 Laravel artisan コマンドは、スタブ コードを作成するときの親友です。次の

artisan

コマンドを使用して、Post モデルの戦略を作成できます。 リーリー ご覧のとおり、すべての CRUD メソッドを作成するために --model=Post パラメーターを提供します。そうでない場合は、空のポリシー クラスが作成されます。新しく作成されたポリシー クラスは、

app/Policies/PostPolicy.php

にあります。 リーリー これを次のコードに置き換えてみましょう。 リーリー 戦略クラスを使用できるようにするには、次のコード スニペットに示すように、Laravel サービス プロバイダーに戦略クラスを登録する必要があります。

リーリー

$policies

属性にポリシー マッピングを追加しました。これは、CRUD 操作を承認するために適切なポリシーメソッドを呼び出すように Laravel に指示します。

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

没有模型的策略方法

PostPolicy 策略类中的 create 方法仅采用单个参数,这与采用两个参数的其他模型方法不同。一般来说,第二个参数是模型对象,您将在执行授权时使用它。但是,在 create 方法的情况下,您只需要检查是否允许相关用户创建新帖子。

在下一节中,我们将了解如何使用自定义策略类。

如何使用我们的自定义策略类

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

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 模型操作。

User 模型提供了两种有用的授权方法 — cancantcan 方法用于检查当前用户是否能够执行某个操作。而与 can 方法对应的 cant 方法,用于判断动作是否无法执行。

让我们从控制器中获取 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 模型通过策略授权操作的演示。或者,如果您在控制器中授权某个操作,则也可以使用控制器助手。

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

如您所见,如果您使用控制器助手,则无需加载 User 模型。

如何通过中间件使用策略

或者,Laravel 还允许您使用中间件授权操作。让我们快速查看以下代码片段,了解如何使用中间件来授权模型操作。

Route::put('/post/{post}', function (Post $post) {
    // Currently logged-in user is allowed to update this post.... 
})->middleware('can:update,post');

在上面的示例中,它将使用 can 中间件。我们传递两个参数:第一个参数是我们想要授权的操作,第二个参数是路由参数。根据隐式模型绑定的规则,第二个参数会自动转换为 Post 模型对象,并作为第二个参数传递。如果当前登录的用户无权执行 update 操作,Laravel 将返回 403 状态代码错误。

如何将策略与刀片模板结合使用

如果您希望在登录用户被授权执行特定操作时显示代码片段,您还可以在刀片模板中使用策略。让我们快速看看它是如何工作的。

@can('delete', $post)
    <!-- Display delete link here... -->
@endcan

在上述情况下,它只会向有权对 Post 模型执行删除操作的用户显示删除链接。

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

只需确保您不会将门和策略一起用于模型的相同操作,否则会产生问题。这就是我今天的内容,今天就到此为止!

结论

今天,Laravel 授权占据了我文章的中心位置。在文章的开头,我介绍了 Laravel 授权、网关和策略的主要要素。

接下来,我们创建了自定义门和策略,以了解它在现实世界中的工作原理。我希望您喜欢这篇文章,并在 Laravel 环境中学到了一些有用的东西。

对于刚刚开始使用 Laravel 或希望通过扩展来扩展您的知识、网站或应用程序的人,我们在 Envato Market 上提供了多种可供您学习的内容。

以上がLaravel のゲートと戦略の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。