如何在 Laravel 5.3 中执行授权策略?

How can I do Authorization Policies in Laravel 5.3?

我在这里阅读:https://laravel.com/docs/5.3/authorization#writing-policies

我试着喜欢这个

我最喜欢的政策是这样的:

<?php
namespace App\Policies;
use App\User;
use App\Models\Favorite;
use Illuminate\Auth\Access\HandlesAuthorization;
class FavoritePolicy
{
    use HandlesAuthorization;
    public function view(User $user, Favorite $favorite)
    {
        return $user->id === $favorite->user_id;
    }
}

我最喜欢的控制器是这样的:

<?php
use App\Models\Favorite;
...
class FavoriteController extends ApiController
{
    ...
    public function index(Favorite $favorite)
    {
        $this->authorize('view', $favorite);
        return view('profile.favorite');
    }
}

我的 AuthServiceProvider 是这样的:

<?php
namespace App\Providers;
use App\Models\Favorite;
use App\Policies\FavoritePolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
        Favorite::class => FavoritePolicy::class,
    ];
    public function boot()
    {
        $this->registerPolicies();
    }
}

当我运行我的系统显示收藏列表时,出现这样的错误:

Whoops, looks like something went wrong.

1/1 HttpException in Handler.php line 115: This action is unauthorized.

Authorization Policy 的执行是正确的吗?

我在视图方法(FavoritePolicy)中尝试dd($user),结果显示正在记录用户数据。是真的

但是我试了dd($favorite),结果没有显示当前登录用户的收藏夹数据。而我检查table,当前登录用户的收藏夹数据存在

我该如何解决这个问题?

更新

dd($favorite) 结果:

Favorite {#498 ▼
  #fillable: array:3 [▶]
  #connection: null
  #table: null
  #primaryKey: "id"
  #keyType: "int"
  #perPage: 15
  +incrementing: true
  +timestamps: true
  #attributes: []
  #original: []
  #relations: []
  #hidden: []
  #visible: []
  #appends: []
  #guarded: array:1 [▼
    0 => "*"
  ]
  #dates: []
  #dateFormat: null
  #casts: []
  #touches: []
  #observables: []
  #with: []
  +exists: false
  +wasRecentlyCreated: false
}

感谢您在更新中提供更多信息!

所以,您想要显示一个特定 Favorite 实体的详细信息页面,但前提是用户是该实体的所有者?

首先是次要 "issue":通常在 Laravel 中,显示特定实体详细信息的控制器方法称为 show,而不是 indexindex 是显示实体列表(在您的示例中:收藏夹列表)的方法的名称。

关于您的问题:
您的策略检查当前登录的用户是否可以查看空 $favorite(请参阅 post 更新中的 dd($favorite) 输出)。这意味着,$favorite 也未在您的 index 方法中设置。

我想,您定义的路由与此类似:

Route::get('favorite/{id}', 'FavoriteController@index');

这意味着 id 的值作为参数注入到您的 index 方法中,而不是 Favorite 实体。您需要在方法中查询 Favorite 实体。

所以,你的方法应该更像这样:

public function index($favoriteId)
{
    $favorite = Favorite::findOrFail($favoriteId);
    $this->authorize('view', $favorite);
    return view('profile.favorite')->with('favorite', $favorite);
}

希望对您有所帮助!如果没有,请添加评论!