13
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Laravel 6.x】authorizeResource() の罠とその対処法

Posted at

Laravel の authorizeResource() を使って認可の実装をしようと思ったとき、index ページの403エラーが消えなくなって困ったことがあったからここに書いておく。

環境

  • Laravel 6.x

authorizeResource() とは

Laravel6.x 認可

例えば、とあるCRUDアプリケーションに記事投稿用のコントローラがあったとする。
アクションごとに権限を変えたりしたいときには、Policy を使って認可すると思う。

PostController.php
public function show(Request $request, Post $post)
{
    $this->authorize('view', $post);

    // 処理を書く
}

public function create(Request $request)
{
    $this->authorize('create', Post::class);

    // 処理を書く
}

public function update(Request $request, Post $post)
{
    $this->authorize('create', $post);

    // 処理を書く
}

.....しかし、いちいち $this->authorize('xxxx', xxxx); と書くのは面倒くさい。
こんなときに authorizeResource() が使える。
コンストラクタに下記のように書けば、$this->authorize('xxxx', xxxx); の記述なしで自動で各アクションごとの Policy を見に行ってくれる。

PostController.php
public function __construct()
{
    $this->authorizeResource(Post::class, 'post');
}

authorizeResource() はリソースコントローラを使用しているときのみ使用可能

authorizeResource() の罠 (Laravel6.x~)

index アクションは認可を必要としていないはずなのに、index ページにいくと、403エラーになっていた。

結論から書くと、今回かかった罠は Laravel6.x アップグレードガイドに書かれていた。

authorizeResourceメソッドを用いてコントラーへ付加している認可ポリシーは、viewAnyメソッドを定義する必要があります。コントローラのindexメソッドへユーザーがアクセスする時に呼び出されます。定義しないと非認可扱いとなり、コントローラのindexメソッドへの呼び出しは拒否されます。

Laravel6.x アップグレードガイド 認可リソースとviewAny より

index アクションの認可が不要なときも、Policy に index アクション用のメソッド viewAny() を書かなければいけなくなったのだ。

PostPolicy.php
class PostPolicy
{
    public function viewAny(User $user)
    {
        return true;
    }

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

viewAny() メソッドが定義されていない場合、非認可扱いとなり、私の時と同じように index ページで403エラーとなる。

※ Policy のアクション名は index でなく、viewAny() なことに注意

メソッド名対応表

コントローラメソッド ポリシーメソッド
index viewAny
show view
create create
store create
edit update
update update
destroy delete

まとめ

  • Laravel 6.x 以上で authorizeResource() を使っている人は気を付ける
  • アップグレードガイドはよく読む
13
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?