【问题标题】:Laravel 5.5, can't handle policy/authorization exception on constructorLaravel 5.5,无法处理构造函数上的策略/授权异常
【发布时间】:2020-02-07 14:35:12
【问题描述】:

这是我的PostCategoriesController 课程的一部分:

<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\PostCategory;
use Illuminate\Support\Facades\Auth;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\Access\AccessDeniedHttpException;

class PostCategoriesController extends Controller
{

    public function __construct()
    {
        try {
            echo 'The try works.';
            $this->authorizeResource(PostCategoriesController::class);
        } catch (\Exception $err) {
            // Never get here.
            dd('The catch does not. We never see this...');
        }
    }


    public function create()
    {
        // This works... but then I have to repeat it for every action...
        try {
            $this->authorize('create');
            return view('admin.post-categories.create');
        } catch (\Exception $err) {
           //return redirect()->route('admin.welcome');
           return 'You cannot create categories, sorry.';
        }
    }
}

问题出在方法authorizeResource(),它抛出了异常:

Symfony\Component\HttpKernel\Exception\ AccessDeniedHttpException 此操作未经授权。

方法authorizeResource() 不在文档中,但我在其他一些帖子中看到它推荐,例如Laravel policy always falseApply Policy to Resource Controller。也是here

PostCategoryPolicy 类只是从他的方法返回布尔值,例如:

public function update(User $user, PostCategory $postCategory)
{
    return $user->has_role === 1;
}

那么,为什么我不能捕捉到那个异常呢?

【问题讨论】:

    标签: laravel authorization


    【解决方案1】:

    我遇到了同样的问题,根据我自己的要求,我应用了一个适合我的特定解决方案,希望它也适合你

    这更像是处理此异常的通用方式,而不是特定于每个控制器或控制器内的方法

    请参考此文件

    /vendor/laravel/framework/src/Illuminate/Foundation/Exception/Handler.php

    在这个文件中你会看到一个受保护的函数

    protected function prepareResponse($request, Exception $e)
    

    您需要在您自己的 Handler.php 文件中覆盖该函数,该文件可在其中找到

    /app/Exceptions/Handler.php

    只需重写此函数并尝试处理 Synfony Access Denied 异常,我只是复制粘贴了整个代码并在最终返回之前添加了我自己的小代码,以便其他一切都像之前一样工作,唯一的变化是如何处理 AccessDenied 异常

    use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
    
    protected function prepareResponse($request, Exception $e)
    {
        if ($e instanceof AccessDeniedHttpException) {
            // $this->unauthorized is a custom & local function that I created
            // you can try doing dd('yes it works over here');
            return $this->unauthorized($request, $e);
        }
    }
    

    我只是试图解释你的概念,你可以换行

    return $this->unauthorized($request, $e);

    使用您需要的任何类型的 Laravel 代码,例如重定向、dd 等

    希望对你有帮助

    【讨论】:

    • 感谢您的帮助。我现在无法对此进行测试,但是当我在发生此问题的项目中还有其他工作要做时,我会牢记这一点。
    • 这会删除太多没有用的父函数。不是 AccessDeniedHttpException 的异常将被忽略并返回 void。
    • 使用Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException 不起作用,我使用Illuminate\Auth\Access\AuthorizationException
    猜你喜欢
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    • 2011-10-10
    • 2016-01-08
    • 2011-01-23
    相关资源
    最近更新 更多