Laravelでモデルに対するupdate、destroyなどのメソッドに対して、アクセス制御をしたい場合がある。
よくあるのは作成した本人しか編集、削除できないようにする、といった制御。
適用までの流れ
- Policyを作成する
- Policyを登録する
- Policyを適用する
1. Policyを作成する
# modelに対応したPolicyではないため、一からメソッドを追加していく必要がある
$ php artisan make:policy PostPolicy
or
# modelを元にPolicyを作成する(view, create, update, deleteが作成される)
$ php artisan make:policy PostPolicy --model=Post
↓modelを元に作成した時点のPolicy
https://gist.github.com/NAKKA-K/c931d687bd177a87586f1a59a07e2712.js
Policy内のメソッドはcontrollerと対応付ける必要はない。
今回はedit, update, destroyに対して付与したいアクセス制御は同じものなので、Policy内に1つだけメソッドを定義する。
メソッドの戻り値がtrueであれば許可、falseであれば拒否になる。
app/Policy/PostPolicy.php
<?php
namespace App\Policies;
use App\User;
use App\Post;
use Illuminate\Auth\Access\HandlesAuthorization;
class PostPolicy
{
use HandlesAuthorization;
// Postを引数に設定することによって、サービスコンテナによって依存かいけr
public function destructive(User $user, Post $post)
{
// Postを作成したユーザーのみ許可する
return $user->id == $post->user_id;
}
}
2. Policyを登録する
作成したPolicyをmodelに対してマッピングする。
app/Providers/AuthServiceProvider.php
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
\App\Post::class => \App\Policies\PostPolicy::class,
];
3. Policyを適用する
今回はControllerでPolicyを適用する方法を説明する。
まず、ここのcontrollerメソッドにPolicyを適用する方法。
edit, update, destroyなど、適用させたいメソッド全てに記述する必要がある。
app/Http/Controllers/PostController.php
class PostController extends Controller
{
public function edit(Post $post)
{
// Policyのdestructiveメソッドを適用($postは第2引数にあたる)
$this->authorize('destructive', $post);
return view('posts.edit', ['post' => $post]);
}
middlewareとして一括で適用する方法。
app/Http/Controllers/PostController.php
class PostController extends Controller
{
public function __construct()
{
// can(Policy)の、destructiveメソッドの、postに対しての制約をmiddleware指定する。
// edit, update, destoryに対してのみmiddlewareを適用する。
$this->middleware('can:destructive,post')
->only(['edit', 'update', 'destroy']);
}
まとめ
今回はControllerに適用する方法のみ紹介したが、middlewareをrouteから指定する方法や、Bladeに適用し、許可されない場合は表示しない、等といった制御も可能。
参照
※Policyを適用する方法は多数あるため、他の方法も知りたければ以下のURL先を参照。
日本語ドキュメント
公式ドキュメント