LoginSignup
8
2

More than 3 years have passed since last update.

【Laravel】authorizeResourceを使いつつ未ログインユーザーに特定のアクションを許可する

Posted at

authorizeResourceメソッドとは

authorizeResourceメソッドを使うと、コントローラーのCRUDアクションに対して、一括してポリシーによる認可制御を適用できます。

app/Http/Controllers/ArticleController/php
<?php

namespace App\Http\Controllers;

use App\Article;
use App\Http\Requests\ArticleRequest;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function __construct()
    {
        $this->authorizeResource(Article::class, 'article');
    }
    // 略
}

authorizeResourceメソッドと未ログインユーザー

authorizeResourceメソッドは便利ではあるのですが、認可されるにはユーザーが認証済みであることが必須であるため、アプリケーションの要件によっては使いづらい場合があります。

例えば、Qiitaでは未登録・未ログインユーザーでも各記事を参照できますが、このように参照系であるindexアクションやshowアクションを未ログインユーザー(ゲストユーザー)でも実行させたいとします。

しかし、authorizeResourceメソッドを使っていると、たとえポリシー側の対応するメソッド(viewAny, view)で一律trueを返していたとしても、未ログインユーザーには403がレスポンスされます。

app/Policies/ArticlePolicy.php
<?php

namespace App\Policies;

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

class ArticlePolicy
{
    use HandlesAuthorization;

    public function viewAny(User $user)
    {
        return true; // 一律trueを返していても、未ログインユーザーは403になってしまう
    }

    public function view(User $user, Article $article)
    {
        return true; // 同上
    }
    // 略
}

認可の条件としてログイン済みを必須としない

認可の条件として、ログイン済みを必須としないようにするにはUserクラスの型宣言をnullable(?User)にします。

app/Policies/ArticlePolicy.php
// 略
    public function viewAny(?User $user)
    {
        return true;
    }
// 略

このようにすると、未ログインユーザーでも該当のアクションを実行できます。

なお、その場合もポリシーのメソッドは実行されますので、

app/Policies/ArticlePolicy.php
// 略
    public function viewAny(?User $user)
    {
        return false; 
    }
// 略

falseを返した場合、未ログインユーザーも403になります。

未ログインユーザーが無条件に認可されるわけではありませんので注意してください。

環境

Laravel 6.x

参考

8
2
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
8
2