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

Posted

技术标签:

【中文标题】如何在 Laravel 5.3 中执行授权策略?【英文标题】:How can I do Authorization Policies in Laravel 5.3? 【发布时间】:2017-03-04 17:10:59 【问题描述】:

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

我试着喜欢这个

My FavoritePolicy 是这样的:

<?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;
    

我的FavoriteController是这样的:

<?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();
    

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

哎呀,好像出了点问题。

Handler.php 第 115 行中的 1/1 HttpException:此操作是 未经授权。

Authorization Policies 的实现方式是正确的?

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

但是我尝试dd($favorite),结果没有显示当前登录用户的收藏数据。而我在表格中查看,当前登录的用户的收藏数据是存在的

我该如何解决这个问题?

更新

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

【问题讨论】:

dd($favorite) 的输出究竟是什么? 请考虑将 dd() 的输出添加到您的问题中,因为您的评论很难阅读。 【参考方案1】:

感谢您在更新中提供的附加信息!

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

首先是一个小“问题”:通常在 Laravel 中,显示特定实体详细信息的控制器方法称为 show,而不是 indexindex 是显示实体列表的方法的名称(在您的示例中:收藏夹列表)。

关于您的问题: 您的策略会检查当前登录的用户是否可以查看空的 $favorite(请参阅更新后的 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);

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

【讨论】:

顺便说一句,这是一种笨拙的方式。应该有一种方法我们不需要调用控制器。

以上是关于如何在 Laravel 5.3 中执行授权策略?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.3 在策略失败时传递 AuthorizationException 消息

在 Laravel 5.5 中测试授权策略时遇到问题

Laravel 5.3 保护下载文件的正确方法

如何在 jwt laravel 5.3 中处理令牌到期?

任何想法如何使用 vue js 和 vue 路由器在 laravel 5.3 中进行基于会话的身份验证

从 curl 使用 Auth0 调用 Laravel 5.3 API 时未经授权的用户