首页 > 解决方案 > 非身份验证路由上的“找不到 CSRF 令牌”

问题描述

我正在为一家小型企业创建一个 Laravel 网站。有一个公共前端和一个用于管理数据、客户信息和博客的“管理面板”。

我创建了一个“公共控制器”来管理在公共路由(主页、隐私政策、画廊等)上发出的请求,它没有实现 Auth 中间件,并且我为博客和仪表板之类的东西设置了单独的控制器实现 Auth 中间件并执行通常的 CRUD。

有两种布局 - 一种“管理员”和一种“用户”,不同之处在于导航栏的显示方式和内容@yield 周围的包装元素。两种布局都@include 一个带有标签的“head”布局,包括 CSRF 令牌。

我的问题是,每当我访问不是“/login”、“/admin”或“/dashboard”的页面时(一旦通过身份验证就可以访问仪表板),我会在控制台中收到有关 CSRF 令牌的错误。

CSRF 令牌在所有页面的 HTML 中可见,Auth 和非 Auth,但它仅在系统不提供的“/login”(以及 make:auth 提供的其他默认 Auth 页面)和“/dashboard”上不要大惊小怪。

我试过了:

let token = document.head.querySelector('meta[name="csrf-token"]');

let token = $('meta[name="csrf-token"]').attr('content');

网页.php

Route::get('/admin', function () {
    if ( Auth::user() ) {
        return redirect('dashboard');
    } else {
        return view('auth.login');
    }
});
Auth::routes();
Route::get('/', 'PublicController@index')->name('home');
Route::get('/dashboard', 'DashController@index')->name('dashboard.index');

user.blade.php (非身份验证路由的“公共”布局)admin.blade.php (身份验证路由的“私有”布局[内部])

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
@include('layouts.head')
<body>
    <div id="app">
...

head.blade.php:

<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">

<title>@yield('title')</title>

<script src="{{ asset('js/app.js') }}" ></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js">/script>

<link href="{{ asset('css/app.css') }}" rel="stylesheet">
@yield('css')

公共控制器.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PublicController extends Controller
{
    /**
     * Show the home page
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        return view('home');
    }
}

破折号控制器.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DashController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        return view('dashboard.index');
    }
}

我可能忽略了一些明显的东西,但我真的不确定现在该去哪里,因为我现在已经在谷歌上尝试了所有答案,尽管你不需要被授权的页面之间存在明显的相关性。 CSRF 和那些检查你是否是 Auth 用户的人都很好,即使两者都包含相同的“头部”布局,其中包含 CSRF。

编辑

请求的 Kernel.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \App\Http\Middleware\TrustProxies::class,
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];

/**
 * The priority-sorted list of middleware.
 *
 * This forces non-global middleware to always be in the given order.
 *
 * @var array
 */
protected $middlewarePriority = [
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \App\Http\Middleware\Authenticate::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];
}

标签: phplaravelcsrflaravel-blade

解决方案


推荐阅读