Laravel 策略授权的自定义消息

Mar*_*aro 6 policy authorization laravel laravel-5 laravel-5.8

在我的 Laravel 5.8 项目中,我正在实施一个类似于 Stack Exchange 的声誉系统:例如,用户只有拥有“3 级”声誉才能回复讨论。

我想在我的 DiscussionPolicy 文件中使用 Laravel 的策略系统来构建权限逻辑:

public function reply(User $user)
{
    $result = true;
    if ($user->current_level < 3) {
        $result = false;
        //I want to inject a custom error message here
    }
    return $result;
}
Run Code Online (Sandbox Code Playgroud)

一切正常,但用户在没有任何解释的情况下得到 403 页面,我想找到一种优雅的方式告诉他们他们无法执行该操作,因为他们没有 3 级。

您能否建议一种以某种方式注入此消息的方法,以将其显示在我的自定义 403.blade.php 页面中?我已经能够通过在会话中闪烁变量来做到这一点,但我认为这并不优雅,我想使用类似 MessageBag (Illuminate\Support\MessageBag) 的东西。

LARAVEL 8.x:检查这个答案

Ton*_*ony 8

当我到达这里搜索如何从策略方法返回消息时,我想我应该添加这个答案,因为我维护的代码仅false在不允许操作时返回。

当前文档Illuminate\Auth\Access\Response从您的策略方法返回一个实例:

...
use Illuminate\Auth\Access\Response;

public function update(User $user, Post $post)
{
    return $user->id === $post->user_id
                ? Response::allow()
                : Response::deny('You do not own this post.');
}
Run Code Online (Sandbox Code Playgroud)


Loe*_*oek 7

答案在评论中给出,放在这里以供参考:

Laravel 通过trait 中的deny()函数提供了这个功能HandlesAuthorization。该deny()函数抛出一个UnauthorizedException但允许您指定一条消息而不是抛出一个普通的异常。

替换为return false它,您可以发送自定义消息以在异常处理程序中呈现。

例子:

public function reply(User $user)
{
    if ($user->current_level < 3) {
        $this->deny('Sorry, your level is not high enough to do that!');
        // Laravel 6+ requires you to return the deny(), see following line
        // return $this->deny('Sorry, your level is not high enough to do that!');
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 你必须 `return $this-&gt;deny()`,至少在 Laravel 6 上 (6认同)