在 App::abort(403) 之后抑制 Laravel 日志中的堆栈跟踪转储

Posted

技术标签:

【中文标题】在 App::abort(403) 之后抑制 Laravel 日志中的堆栈跟踪转储【英文标题】:Suppressing stack trace dump in Laravel log after App::abort(403) 【发布时间】:2014-06-12 15:32:31 【问题描述】:

我正在为 Laravel 4.1 应用程序设置自定义 Acl。

我的 Routes.php 文件应用了一个前置过滤器:

// Global authenticator
Route::filter('auth.vle', function()

    return (new vleAuth)->authenticate();
);
// Authenticate all requests, except those to /login, /logout and /forgottenpassword
Route::whenRegex('/^(?!login|logout)(.*)$/', 'auth.vle');

和我的 vleAuth authenticate() 方法:

public function authenticate()

    $this->acl = new vleAclService();
    $endpoint = Route::current()->getAction()['controller'];
    if (!$this->acl->validateEndpoint($endpoint)) 
        Log::info('Routing', array( Route::current()->getUri(), $endpoint));
        App::abort(403, 'Unauthorized action.');
    

当我访问我有权访问的端点时,没有问题;当我访问一个我无权访问的端点时,我会收到一条Forbidden - We're really sorry but you don't have the necessary permissions to access this page. 消息,因此就“前端”而言,身份验证工作正常,并且日志中的路由信息​​包含这个出来了。

但是,每当我尝试访问未通过身份验证的端点时,我也会在 Laravel 日志中得到一个堆栈跟踪信息

[2014-06-12 15:00:16] production.INFO: ROUTE VALIDATION ["View_Reviews_ReviewsController@getIndex",false] []
[2014-06-12 15:00:16] production.ERROR: exception 'Symfony\Component\HttpKernel\Exception\HttpException' with message 'Unauthorized action.' in /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:875
Stack trace:
#0 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(211): Illuminate\Foundation\Application->abort(403, 'Unauthorized ac...')
#1 /srv/api/laravel/app/controllers/vleAuth.php(104): Illuminate\Support\Facades\Facade::__callStatic('abort', Array)
#2 /srv/api/laravel/app/controllers/vleAuth.php(104): Illuminate\Support\Facades\App::abort(403, 'Unauthorized ac...')
#3 /srv/api/laravel/app/routes.php(20): vleAuth->authenticate()
#4 [internal function]: closure(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#5 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(199): call_user_func_array(Object(Closure), Array)
#6 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(154): Illuminate\Events\Dispatcher->fire('router.filter: ...', Array, true)
#7 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Routing/Router.php(1399): Illuminate\Events\Dispatcher->until('router.filter: ...', Array)
#8 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Routing/Router.php(1262): Illuminate\Routing\Router->callRouteFilter('auth.vle', Array, Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#9 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Routing/Router.php(1246): Illuminate\Routing\Router->callPatternFilters(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#10 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Routing/Router.php(996): Illuminate\Routing\Router->callRouteBefore(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#11 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Routing/Router.php(968): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#12 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(738): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#13 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(708): Illuminate\Foundation\Application->dispatch(Object(Illuminate\Http\Request))
#14 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Http/FrameGuard.php(38): Illuminate\Foundation\Application->handle(Object(Illuminate\Http\Request), 1, true)
#15 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Session/Middleware.php(72): Illuminate\Http\FrameGuard->handle(Object(Illuminate\Http\Request), 1, true)
#16 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Cookie/Queue.php(47): Illuminate\Session\Middleware->handle(Object(Illuminate\Http\Request), 1, true)
#17 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Cookie/Guard.php(51): Illuminate\Cookie\Queue->handle(Object(Illuminate\Http\Request), 1, true)
#18 /home/vagrant/vleAppV2/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Illuminate\Cookie\Guard->handle(Object(Illuminate\Http\Request), 1, true)
#19 /home/vagrant/vleAppV2/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(606): Stack\StackedHttpKernel->handle(Object(Illuminate\Http\Request))
#20 /home/vagrant/vleAppV2/public/index.php(49): Illuminate\Foundation\Application->run()
#21 main [] []

我试图抑制这一点,因为我不希望日志充满堆栈跟踪;我在日志中真正需要的只是我自己记录的日志信息。

我尝试通过在 app/global.php 中注册一个新的错误处理函数来抑制它:

App::error(function(Exception $exception, $code)

    // Don't log 403s
    if ($exception instanceof Symfony\Component\HttpKernel\Exception\HttpException) 
        return;
    

    Log::error($exception);
);

但这似乎根本没有任何效果。

我也尝试将App:abort() 中的vleAuth.authenticate() 包装在try/catch 块中,但异常似乎在此捕获之前已经被处理,所以它也没有帮助。

我已经重新运行 composer dump-autoload 以重建所有适当的自动加载,并重新启动服务器以防旧脚本在 OpCache 中得到帮助。

谁能告诉我应该如何抑制这个堆栈跟踪?

【问题讨论】:

如果您已将 App::abort 调用包装在 try/catch 中并且仍在调用 App::error 回调,则最可能的罪魁祸首似乎是使用了错误的命名空间,或者您的文件没有正确更新(可能是由于源代码控制、opcache 或其他原因)。 【参考方案1】:

解决方案是从自定义错误处理函数返回响应,而不是返回 null

App::error(function(Exception $exception, $code)

    // Don't log 403s
    if ($exception instanceof Symfony\Component\HttpKernel\Exception\HttpException) 
        return Response::view('errors.403', array(), 403);
    

    Log::error($exception);
);

这仍然会正确显示 403 页面,但会覆盖调用生成堆栈跟踪的默认错误处理程序

【讨论】:

以上是关于在 App::abort(403) 之后抑制 Laravel 日志中的堆栈跟踪转储的主要内容,如果未能解决你的问题,请参考以下文章

APACHE,HTACCESS:afficher des pages d';erreurs personnalisÃ

宝塔配置完SSL之后访问显示403 forbidden问题解决

宝塔配置完SSL之后访问显示403 forbidden问题解决

在函数中抑制 cout 输出

macOS Big Sur apache2环境配置好之后一直报403错误易忽略的点

macOS Big Sur apache2环境配置好之后一直报403错误易忽略的点