ユーザー認証


##ユーザー認証

  • はじめに
  • ゲート
      ##ゲートの書き込み
    • ##認可アクション
    • ##ゲートインターセプトチェック
    • ポリシーの作成
  • ポリシーの生成
  • ストラテジ メソッド
  • ユーザー モデル経由
  • #ミドルウェア経由
    • #コントローラー ヘルパー関数経由
    • ブレード テンプレート経由
はじめに

Laravel は、すぐに使えるユーザー認証サービスを提供するだけでなく、ユーザー認証アクションを処理する簡単な方法も提供します。 Laravelの認可方法もユーザー認証と同様にシンプルで、主にゲートとポリシーの2つの認可方法があります。

ゲートとストラテジーは、ルーティングとコントローラーにたとえることができます。ゲートは単純なクロージャベースの認可方法を提供しますが、ポリシーはコントローラに似ており、特定のモデルまたはリソースを中心にロジックをグループ化することで認可認証を実装します。まずゲートを探索し、それから戦略を検討します。
アプリケーションを構築するとき、ゲートのみを使用するか、ストラテジのみを使用するかを選択する必要はありません。おそらくほとんどのアプリケーションにはゲートとポリシーの両方が含まれており、それらは正常に動作します。ゲートは主に、管理者パネルの表示など、モデルとリソースが関連しない場所で使用されます。対照的に、戦略は特定のモデルまたはリソース内で使用する必要があります。

#ゲート

##

Gates の記述

Gates は、ユーザーが特定のアクションを実行する権限を持っているかどうかを判断するために使用されるクロージャ関数であり、一般的な方法は、
App\Providers\AuthServiceProvider でそれを使用することです。 Gate を定義します。Gates は常に最初のパラメーターとしてユーザー インスタンスを受け取り、関連する Eloquent モデルなどのオプションのパラメーターを受け取ることができます:

/**
 * 注册任意用户认证、用户授权服务。
 *
 * @return void
 */
 public function boot(){ 
    $this->registerPolicies();    
    Gate::define('update-post', function ($user, $post) {  
          return $user->id == $post->user_id;  
       });
  }

Gates は同様のコントローラーも使用できますメソッド Class@method 定義するスタイル コールバック文字列:

/**
 * 注册任意用户认证、用户授权服务。
 *
 * @return void
 */
 public function boot(){ 
    $this->registerPolicies();    
    Gate::define('update-post', 'App\Policies\PostPolicy@update');
   }

ResourceGates

resource メソッドを使用して定義することもできます複数のゲート メソッドを同時に実行:

Gate::resource('posts', 'App\Policies\PostPolicy');

上記の手動定義は、次のゲート定義と同じ効果があります:

Gate::define('posts.view', 'App\Policies\PostPolicy@view');
Gate::define('posts.create', 'App\Policies\PostPolicy@create');
Gate::define('posts.update', 'App\Policies\PostPolicy@update');
Gate::define('posts.delete', 'App\Policies\PostPolicy@delete');

デフォルトでは、view# は ##, ## として定義されます#createupdate、および delete メソッド。 3 番目のパラメータとして配列を resource メソッドに渡します。デフォルトのメソッドをオーバーライドしたり、デフォルトのメソッドに追加したりできます。配列のキーは機能の名前を定義し、値はメソッドの名前を定義します。たとえば、次のコードは 2 つの新しいゲート定義 (posts.imageposts.photo:

Gate::resource('posts', 'PostPolicy', [ 
   'image' => 'updateImage',    
   'photo' => 'updatePhoto',
 ]);

#) を作成します。

##承認されたアクション
ゲートを使用してアクションを承認する場合は、

allows

または

denies メソッドを使用する必要があります。現在の認証済みユーザーをこれらのメソッドに渡す必要はないことに注意してください。 Laravel は認証されたユーザーを自動的に処理し、それを gete クロージャー関数に渡します。

if (Gate::allows('update-post', $post)) { 
   // 指定当前用户可以进行更新...
  }
if (Gate::denies('update-post', $post)) { 
   // 指定当前用户不能更新...
  }
特定のユーザーがアクションへのアクセスを許可されているかどうかを確認したい場合は、 Gate## を使用できます。ファサードの

#forUser

メソッド:

if (Gate::forUser($user)->allows('update-post', $post)) {
    // 用户可以更新...
  }
if (Gate::forUser($user)->denies('update-post', $post)) {
    // 用户不能更新...
  }

ゲート インターセプト チェック

特定のユーザーにすべての機能を付与したい。したがって、
before

メソッドを使用して、他のすべての承認チェックの前に実行されるコールバックを定義できます。

Gate::before(function ($user, $ability) { 
   if ($user->isSuperAdmin()) {   
        return true;  
    }
});

before コールバック メソッドが null 以外の結果を返した場合、その結果が検査結果として考慮されます。

after メソッドを使用して、各承認チェックの後に実行されるコールバックを定義できます。ただし、

after

コールバック メソッドから承認チェックの結果を変更することはできません。

Gate::after(function ($user, $ability, $result, $arguments) { 
   //
});
は、before チェックと同様です。 ## コールバックが null 以外の結果を返した場合、その結果はチェック結果として扱われます。

#ポリシーの作成

ポリシーの生成

ポリシーは、特定のモデルまたはリソースの認可ロジックを編成するクラスです。たとえば、アプリケーションがブログの場合、ブログを作成または更新するときに、ユーザーのアクションを承認するための Post モデルと対応する PostPolicy が必要になることがあります。

artisan command artisan command 職人コマンドの make:policy 職人コマンド コマンドを使用して、ポリシーを生成できます。生成されたポリシーは、app/Policies

ディレクトリに配置されます。このディレクトリがアプリケーションに存在しない場合は、Laravel が自動的にディレクトリを生成します:

php artisan make:policy PostPolicy
make:policy このコマンドは空のポリシー クラスを生成します。生成するクラスに基本的な「CRUD」戦略メソッドが含まれている場合は、コマンドの実行時に --model

オプションを指定できます:
php artisan make:policy PostPolicy --model=Post

{tip} すべての戦略は次のとおりです。 Laravel のサービス コンテナを通じて解析されるため、ポリシー コンストラクターで必要な依存関係をタイプヒントで指定し、それらを自動的に挿入できます。

#ポリシーの登録

ポリシーが存在したら、登録する必要があります。新しい Laravel アプリケーションに含まれる AuthServiceProvider には、さまざまなモデルをポリシーにマップする policies プロパティがあります。ポリシーを登録すると、指定されたモデルにアクセスするアクションを承認するときにどのポリシーを使用するかを Laravel に指示します:

<?php
    namespace App\Providers;
    use App\Post;use App\Policies\PostPolicy;
    use Illuminate\Support\Facades\Gate;
    use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
    class AuthServiceProvider extends ServiceProvider{  
      /**
     * 应用的策略映射。
     *
     * @var array
     */ 
     protected $policies = [  
          Post::class => PostPolicy::class,  
       ];   
     /**
     * 注册任意应用认证、应用授权服务
     *
     * @return void
     */ 
   public function boot()   
    {     
       $this->registerPolicies();   
            //   
     }
   }

ポリシー自動検出

モデルとポリシーが次のとおりである限り標準的な Laravel の命名 慣例により、Laravel はモデル戦略を手動で登録する代わりに、自動的に戦略を検出できます。具体的には、ポリシーは、モデルが含まれるディレクトリの下の Policies ディレクトリに配置する必要があります。したがって、たとえば、モデルを app ディレクトリに配置し、ポリシーを app/Policies ディレクトリに配置できます。さらに、ポリシー名はモデル名と一致し、Policy サフィックスが付いている必要があります。したがって、User モデルは UserPolicy クラスに対応します。

独自のポリシー検出ロジックを提供する場合は、Gate::guessPolicyNamesUsing メソッドを使用してカスタム コールバックを登録できます。通常、このメソッドはアプリケーションの AuthServiceProviderboot メソッドから呼び出す必要があります。

use Illuminate\Support\Facades\Gate;
Gate::guessPolicyNamesUsing(function ($modelClass) {
    // return policy class name...
 });

{note} AuthServiceProvider で明示的マッピングされているポリシーは、自動検出ポリシーよりも優先されます。

ライティング戦略

##

戦略メソッド

認可ポリシーを登録すると、認可後の各アクションのメソッドを追加できます。たとえば、PostPolicyupdate メソッドを定義します。このメソッドは、指定された User が指定された Post インスタンスを更新できるかどうかを決定します。

update メソッドは、パラメータとして User インスタンスと Post インスタンスを受け取り、true または false# を返す必要があります。 ## ユーザーが指定された Post を更新する権限を持っているかどうかを示します。したがって、この例では、ユーザーの id が投稿内の user_id と一致するかどうかを判断する必要があります。

<?php
   namespace App\Policies;use App\User;
   use App\Post;class PostPolicy{  
       /**
     * 判断该方法能否被用户操作。
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */ 
  public function update(User $user, Post $post) 
    {    
       return $user->id === $post->user_id;   
     }
 }

この認可ポリシーに対して追加のメソッドを引き続き定義できます。たとえば、

view または delete メソッドを定義して Post の複数の動作を承認したり、カスタム戦略メソッドに好きな名前を付けることもできます。 。

{ヒント} Artisan コンソールでストラテジーを生成するときに

--model オプションを使用すると、view が含まれます。 createupdate、および delete アクション メソッド。

#モデル メソッドは含まれません

一部のポリシー メソッドは、現在認証されているユーザーのみをパラメーターとして受け取ります。認可関連のモデルインスタンスを渡す方法。最も一般的なアプリケーション シナリオは、

create

アクションを承認することです。たとえば、ブログを作成している場合、まず現在のユーザーにブログを作成する権限があるかどうかを確認することができます。 モデル インスタンスを渡す必要のないストラテジ メソッド (

create

メソッドなど) を定義する場合、モデル インスタンスをパラメーターとして受け取りません。許可されたユーザーのみをパラメーターとして受け入れるようにこのメソッドを定義する必要があります。

/**
 * 判断用户是否可以创建请求。
 *
 * @param  \App\User  $user
 * @return bool
 */
 public function create(User $user){ 
    //
 }

ゲスト ユーザー

デフォルトでは、受信 HTTP リクエストが認証されたユーザーによって開始されたものでない場合、すべてのゲートと戦略は自動的に

false

を返します。ただし、「オプション」タイプ ヒントを宣言するか、ユーザー パラメーター定義に null デフォルト値を指定することで、これらの認可チェックをゲートやポリシーに渡すことができます:

<?php
     namespace App\Policies;
     use App\User;use App\Post;class PostPolicy{  
       /**
     * 判断用户是否能更新指定帖子。
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */ 
  public function update(?User $user, Post $post)  
    {     
      return $user->id === $post->user_id;  
     }
  }
# ##############################

ポリシー フィルター

特定のユーザーに対して、指定したポリシーを通じてすべてのアクションを承認することができます。この目標を達成するには、ストラテジーで before メソッドを定義します。 before メソッドは、ポリシー内の他のすべてのメソッドの前に実行され、指定されたポリシー メソッド以外のアクションが判断を実行することを許可する方法を提供します。この機能の最も一般的なシナリオは、アプリケーションの管理者にすべてのアクションへのアクセスを許可することです。

public function before($user, $ability){
    if ($user->isSuperAdmin()) { 
       return true; 
     }
 }

ユーザーに対するすべての許可を拒否したい場合は、before# で ## を返す必要があります。 ## メソッド #false 。戻り値が null の場合、このポリシーでは承認は失敗します。

{note} チェック対象の関数名に一致するメソッドがクラスに含まれていない場合、ストラテジー クラスの
before

メソッドは呼び出されません。

ポリシー承認アクションを使用する

#ユーザーモデルを通じて
Laravel の組み込み

User

モデルには、アクションを承認するための 2 つの便利なメソッド

cancant が含まれています。この can メソッドでは、承認されたアクションと関連モデルを指定する必要があります。たとえば、ユーザーが指定された Post モデルを更新する権限を持っているかどうかを判断するには:

if ($user->can('update', $post)) { 
   //
}
"指定されたモデルの ポリシーが登録されている

" の場合、

can このメソッドは、適切なストラテジを自動的に呼び出し、ブール値を返します。このモデルにストラテジーが登録されていない場合、can メソッドは、指定されたアクション名に一致するクロージャーベースのゲートの呼び出しを試みます。

モデル アクションを指定する必要はありません

create

などの一部のアクションでは、モデル インスタンスを指定する必要がないことに注意してください。この場合、クラス名を

can メソッドに渡します。このクラス名は、使用するポリシー認可アクションを決定するために使用されます:

use App\Post;if ($user->can('create', Post::class)) { 
   // 执行相关策略中的 "create" 方法...
 }

Via middleware
Laravel には次のものが含まれますリクエストがルートまたはコントローラーに到達する前にアクションを承認できるミドルウェア。デフォルトでは、

Illuminate\Auth\Middleware\Authorize

ミドルウェアは、

App\Http\Kernel クラスの can キーに割り当てられます。承認されたユーザーがブログを更新する例を使用して、can ミドルウェアの使用方法を説明します。

use App\Post;Route::put('/post/{post}', function (Post $post) {
    // 当前用户可以进行更新操作...
})->middleware('can:update,post');
この例では、can

ミドルウェア 2 を渡しました。パラメーター。最初のパラメータは承認が必要なアクションの名前で、2 番目のパラメータはポリシー メソッドに渡すルーティング パラメータです。この場合、「暗黙的なルート バインディング」を使用し、

Post モデルが戦略メソッドに渡されます。ユーザーが指定されたアクションへのアクセスを許可されていない場合、このミドルウェアは 403 ステータス コードを含む HTTP 応答を生成します。

指定されたモデルを必要としないアクション

同様に、create などの一部のアクションはモデル インスタンスを必要としない場合があります。この場合、クラス名をミドルウェアに渡すことができます。このアクションを承認するとき、このクラス名は、使用するポリシーを決定するために使用されます:

Route::post('/post', function () {
    // 当前用户可以进行创建操作...
 })->middleware('can:create,App\Post');

コントローラー ヘルパー関数を通じて

User モデルでヘルパー メソッドを提供することに加えて、Laravel は、App\Http\Controllers\Controller 基本クラスを継承するコントローラー用の便利な も提供します。 authorize メソッド。 can メソッドと同様に、このメソッドは承認するアクションと関連モデルをパラメーターとして受け取る必要があります。このアクションが承認されていない場合、authorize メソッドは Illuminate\Auth\Access\AuthorizationException の例外をスローし、Laravel のデフォルトの例外ハンドラーはこの例外を # の例外に変換します。 ##403 HTTP 応答ステータス コード。

<?php
     namespace App\Http\Controllers;
     use App\Post;use Illuminate\Http\Request;
     use App\Http\Controllers\Controller;
     class PostController extends Controller{  
       /**
     * 更新指定博客帖子。
     *
     * @param  Request  $request
     * @param  Post  $post
     * @return Response
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */ 
   public function update(Request $request, Post $post)  
     {     
       $this->authorize('update', $post);     
       // 当前用户可以更新博客...   
      }
  }

モデルのアクションを指定する必要はありません

前述したように、

create などの一部のアクションは指定する必要がありません。モデル インスタンスのアクション。この場合、クラス名を authorize メソッドに渡すことができます。このアクションを承認する場合、このクラス名を使用して、どのポリシーを使用するかを決定します。

/**
 * 创建一个新的博客
 *
 * @param  Request  $request
 * @return Response
 * @throws \Illuminate\Auth\Access\AuthorizationException
 */
 public function create(Request $request){ 
    $this->authorize('create', Post::class);  
    // 当前用户可以新建博客...
  }

認可リソース コントローラー

リソース コントローラーを使用している場合は、コントローラー コンストラクターで

authorizeResource メソッドを使用できます。このメソッドは、適切な can ミドルウェアをリソース コントローラーの対応するメソッドにアタッチします。

authorizeResource このメソッドは、テンプレート クラス名を最初のパラメーターとして受け取り、モデル ID を含むルート/リクエスト パラメーターの名前を 2 番目のパラメーターとして受け取ります。 # #{ヒント} make:policy

コマンドを
--model

オプションとともに使用すると、指定されたモデルに基づいてポリシー クラスを迅速に生成できます。ポリシー PostPolicy --model=Post

ブレード テンプレートを使用するブレード テンプレートを作成するとき、ページの特定の部分だけを表示したい場合があります。指定されたアクションへのアクセスを許可されたユーザーに表示されます。たとえば、ブログを更新する権限を持つユーザーにのみ、更新されたフォームを表示したい場合があります。この場合、

@can
@cannot

などの一連の命令を使用できます。

<?php
    namespace App\Http\Controllers;
    use App\Post;use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    class PostController extends Controller{ 
       public function __construct() 
          {       
            $this->authorizeResource(Post::class, 'post');  
           }
     }

これらの命令は @if と書かれています。および @unless ステートメントへのショートカット。

@can

ステートメントと @cannot ステートメントは、それぞれ次のステートメントに変換されます:

@can('update', $post) 
  <!-- The Current User Can Update The Post -->
@elsecan('create', App\Post::class)  
  <!-- The Current User Can Create New Post -->
@endcan
@cannot('update', $post) 
  <!-- The Current User Can't Update The Post -->
@elsecannot('create', App\Post::class)
  <!-- The Current User Can't Create New Post -->
 @endcannot

モデルに依存しないアクション

他のほとんどの承認メソッドと同様、アクションにモデル インスタンスが必要ない場合は、クラス名を @ can および @ に渡すことができます。できません 手順:

@if (Auth::user()->can('update', $post))  
  <!-- The Current User Can Update The Post -->
@endif
@unless (Auth::user()->can('update', $post))   
 <!-- The Current User Can't Update The Post -->
@endunless
この記事は、LearnKu.com Web サイトで初めて公開されました。