我有一个Laravel应用程序,可以获得合理的流量. 为了更好地处理TokenMismatchException类型的异常(当会话生存期到期然后用户提交表单时会抛出它),我更改了异常处理程序的render()方法,如下所
为了更好地处理TokenMismatchException类型的异常(当会话生存期到期然后用户提交表单时会抛出它),我更改了异常处理程序的render()方法,如下所示:
/** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $e * @return \Illuminate\Http\Response */ public function render($request, Exception $e) { if ($e instanceof \Illuminate\Session\TokenMismatchException){ return redirect($request->fullUrl())->with('error',"Sorry your session has expired please resubmit your request."); } return parent::render($request, $e); }
这对于正常请求工作正常,而不是抛出异常,它设置会话闪存消息并重定向回请求的页面.但是,我注意到以下请求仍然抛出了许多这些异常:
/autodiscover/autodiscover.xml
我知道上面的内容与Exchange有关,所以它可能不是恶意的.
我很困惑的是a)为什么这个unrouted url触发了Laravel的CSRF保护,以及b)为什么我的更新处理程序没有捕获异常?
我已经尝试为此网址添加路由,并手动抛出404,但这没有帮助.
我该怎么做才能防止抛出这些异常?
编辑 – 按要求堆栈跟踪:
2015-10-26 11:44:38] production.ERROR: exception 'Illuminate\Session\TokenMismatchException' in /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php:53 Stack trace: #0 [internal function]: Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure)) #1 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array) #2 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(54): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #3 [internal function]: Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure)) #4 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array) #5 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(62): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #6 [internal function]: Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure)) #7 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array) #8 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #9 [internal function]: Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure)) #10 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array) #11 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(59): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #12 [internal function]: Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure)) #13 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array) #14 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(42): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #15 [internal function]: Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure)) #16 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array) #17 [internal function]: Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #18 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): call_user_func(Object(Closure), Object(Illuminate\Http\Request)) #19 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(122): Illuminate\Pipeline\Pipeline->then(Object(Closure)) #20 /var/www/vhosts/sitedomain.com/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(87): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request)) #21 /var/www/vhosts/sitedomain.com/public_html/index.php(53): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request)) #22 {main}因此,解决方案变得相对简单.看起来Laravel的默认行为是处理所有发布(以及可能是put和delete …)请求,无论它们是否在路由中定义.
所以我们可以在VerifyCsrfToken中间件$except数组中添加一个例外:
protected $except = [ 'autodiscover/autodiscover.xml' ]
添加上述内容后,不再抛出我的TokenMismatchException.