Laravel авария печенья 5 нуля

Сценарий:

Тот же браузер.

  • Вкладка 1: вход в мое приложение laravel.
  • Вкладка 2: вход в мое приложение laravel.
  • Вкладка 2: выход из системы
  • Вкладка 1: нажмите кнопку, которая вызывает перенаправление маршрута, который защищен: Route:: group (['middleware' = > 'auth'], function() { ...

Результат: Laravel 5 сработает, прежде чем он попадет в мой код:

введите описание изображения здесь

Stack

Symfony\Component\Debug\Exception\FatalErrorException Call to a member function setCookie() on null
    vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php:184 __construct
    vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:131 fatalExceptionFromError
    vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:116 handleShutdown
    vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:0 addCookieToResponse
    vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php:72 handle
    vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:125 Illuminate\Pipeline\{closure}
    vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php:36 handle
    vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:125 Illuminate\Pipeline\{closure}
    vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php:40 handle
    vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:125 Illuminate\Pipeline\{closure}
    vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php:42 handle
    vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:125 Illuminate\Pipeline\{closure}
    vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:101 call_user_func:{/home/vagrant/dev/opus-web-app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:101}
    vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:101 then
    vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:115 sendRequestThroughRouter
    vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:84 handle
    public/index.php:53 {main}
    public/index.php:0 [main]

Даже когда я удаляю группу Route:: group (['middleware' = > 'auth'] из моих маршрутов... переход на вкладку 1 к открытым URL-адресам приведет к этой ошибке. Я просто не получаю это.

Как мне избавиться от этого?

Ответ 1

Мне кажется, что проблема заключается в вашей логике в проверке CSRF.

Вот проблема: Вы проверяете, совпадают ли токены, и эта функция следующая:

protected function tokensMatch($request)
{
    $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

    if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
        $token = $this->encrypter->decrypt($header);
    }

    return Str::equals($request->session()->token(), $token);
}

Но если вы посмотрите внимательно, вы увидите, что в возврате он проверяет:

$request->session()->token()

Но сеанс null, поэтому вы получите исключение для попытки запросить метод из null.

Итак, если я не ошибаюсь, все, что вам нужно сделать, это просто добавить дополнительную проверку в if, если в методе handle. Вместо этого:

if ($request && ((
      $this->isReading($request) 
      || $this->excludedRoutes($request) 
      || ($this->tokensMatch($request) && Auth::check())
    )))

У вас должно получиться следующее:

if ($request && ((
      $this->isReading($request) 
      || $this->excludedRoutes($request) 
      || ($request->hasSession() && $this->tokensMatch($request) && Auth::check())
   )))

Таким образом, если сеанс отсутствует, он даже не проверяет, соответствуют ли токены, и он не будет там сбой.

Вы также можете рассмотреть рефакторинг этой части оператора if функции, которая по имени описывает, что вы проверяете, и даже полный оператор if для функции, которая говорит все это. Просто для ясности кода.


Это либо, или вы можете рассмотреть возможность проверки своих других Middlewares, всех, кто касается заголовков запроса и потенциально может отключить заголовки.

Если вы берете код handle функции промежуточного ПО StartSession:

public function handle($request, Closure $next)
{
    $this->sessionHandled = true;
    if ($this->sessionConfigured())
    {
        $session = $this->startSession($request);
        $request->setSession($session);
    }

    // ** HERE ALL OTHER MIDDLEWARES ARE BEING CALL
    $response = $next($request);

    if ($this->sessionConfigured())
    {
        $this->storeCurrentUrl($request, $session);
        $this->collectGarbage($session);
        // ** AFTER ALL OTHER MIDDLEWARES ARE CALLED THE FOLLOWING FUNCTION 
        // TOUCHES THE HEADER AND IS NULL
        $this->addCookieToResponse($response, $session);
    }
    return $response;
}

Итак, возможно, что где-нибудь в любом другом промежуточном программном обеспечении вы касаетесь заголовка и оставляете его нулевым, как указано в вашей ошибке.

Я надеюсь, что это поможет.

Ответ 2

Я понял причину, но я просто не уверен в этом. Надеюсь, кто-то из вас узнает.

В kernel.php:

У меня был 'App\Http\Middleware\VerifyCsrfToken', определенный в черном $middleware, а не $routeMiddleware. когда я переместил его в $routeMiddleware, я перестал получать эту ошибку.

Содержимое VerifyCsrfToken:

class VerifyCsrfToken extends BaseVerifier {

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request && (($this->isReading($request) || $this->excludedRoutes($request) || ($this->tokensMatch($request) && Auth::check()))))
        {
            return $this->addCookieToResponse($request, $next($request));
        }

        return view('sessionOver');
    }

    protected function excludedRoutes($request)
    {
        $routes = [
            'deployPush'  // webhook push for bitBucket.
        ];

        foreach($routes as $route)
            if ($request->is($route))
                return true;

        return false;
    }
}

Ответ 3

Может быть, это будет полезно для вас .check в промежуточном программном обеспечении некоторые считают похожими на это

public function handle($request, Closure $next)
{
    $response = $next($request);

    if ( ! Auth::user()) // Your logic here...
        abort(403, 'Unauthorized action.');

    return $response;
}

Ref:: https://laracasts.com/discuss/channels/general-discussion/disable-global-verifycsrftoken-and-use-as-middleware-doesnt-work-setcookie-on-null

в этом обсуждении обсуждалась некоторая ошибка cookie. Это может помочь вам

Ответ 4

Опытная аналогичная проблема возникла специально при возврате ответа от промежуточного программного обеспечения, и я понял, что это вызвано возвратом return view('my.view.blade'), а не return response()->view('my.view.blade').

Короче говоря, не возвращайте представление напрямую. Закрепите помощника view() помощнику response().

return view('myview.blade'); //wrong
return response()->view('myview.blade'); //works