You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel禁止返回历史中间件失效:登出后仍可访问仪表盘

解决Laravel登出后可返回管理员仪表盘的问题

我创建了一个名为RevalidateBackHistory.php的禁止返回历史中间件,在kernel.php中注册为**'revalidate'**。该中间件在管理员仪表盘上运行正常,但执行sign out(登出)操作后失效,用户仍可返回仪表盘。我通过Route::group将其应用于整个应用,也尝试过仅配置特定路由,但均未解决问题。

相关代码

中间件代码:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class RevalidateBackHistory
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);
        $response->headers->set('Cache-Control','no-cache, no-store, max-age=0, must-revalidate');
        $response->headers->set('Cache-Control: post-check=0, pre-check=0', false);
        $response->headers->set('Pragma','no-cache');
        $response->headers->set('Expires','Sun, 02 Jan 1990 00:00:00 GMT');
        return $response;
    }
}

路由文件web.php:

<?php

use App\Http\Controllers\AdminController;
use App\Http\Controllers\ProductController;
use App\Http\Controllers\StoreController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\ReviewController;
use App\Http\Controllers\CartController;
use App\Http\Controllers\PayPalController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::group(['middleware' => 'revalidate'], function() {

    //Store Routes
    Route::get('store',[StoreController::class, 'index'])->name('store');
    Route::get('/', function () {return redirect()->route('store');});

    //Single Product Page
    Route::get('show/{id?}',[StoreController::class, 'show'])->name('show');

    //Cart Functionalities
    Route::get('cart',[CartController::class, 'cart'])->name('cart');
    Route::post('add-to-cart', [CartController::class, 'addToCart'])->name('add-to-cart');
    Route::get('load-cart-data',[CartController::class, 'cartLoadAjax'])->name('load-cart-data');
    Route::post('update-cart-data',[CartController::class, 'updateCartData'])->name('update-cart-data');

    //Redirect if already authenticated middleware(Admin)
    Route::group(['middleware' => ['auth:web']], function() {

        //Checkout
        Route::get('checkout',[StoreController::class, 'checkOut'])->name('checkout');

        //Create Comment
        Route::post('comments/{id}',[ReviewController::class, 'store'])->name('comment');

        //Paypal 
        Route::post('payment', [PayPalController::class, 'payment'])->name('payment');
        Route::get('payment.success', [PayPalController::class, 'success'])->name('payment.success');

        //getDetails
        Route::get('get.details', [UserController::class, 'getDetails'])->name('get.details');

    });

    //Redirect if already authenticated middleware(Admin)
    Route::group(['middleware' => ['guest:web']], function() {

      //User Login and Registration
      Route::get('UserLogin',[UserController::class, 'UserLogin'])->name('UserLogin');
      Route::post('user.login',[UserController::class, 'UserCustomLogin'])->name('user.login');

      Route::post('UserRegis',[UserController::class, 'customUserRegistration'])->name('UserRegis');  

    });

    Route::group(['middleware' => ['guest:admin']], function() {

      //Admin Register
      Route::get('admin_register',[AdminController::class, 'registration'])->name('GetSignUp');
      Route::post('post_Register',[AdminController::class, 'customRegistration'])->name('aSignUp');  

      //Admin Login
      Route::get('admin_login',[AdminController::class, 'AdminGetLogin'])->name('login');
      Route::post('post_login',[AdminController::class, 'CustomLogin'])->name('aAuth');

    });

    Route::group(['middleware' => ['auth:admin']], function() {
          // define your route, route groups here

              //Dashboard
              Route::get('dashboard',[AdminController::class, 'dashboard'])->name('dashboard');
              
              //SignOut
              Route::get('admin_signout',[AdminController::class, 'signOut'])->name('signout');

              //Products
              Route::get('add_product',[ProductController::class, 'create'])->name('add_product');
              Route::post('save_product',[ProductController::class, 'createProduct'])->name('save_product');
              Route::get('view_products',[ProductController::class, 'viewProducts'])->name('view_products');
            
              //New Edit 
              Route::get('editNew/{id?}',[ProductController::class, 'editNew'])->name('editNew');

              //Update Product Data
              Route::post('update_product/{id}',[ProductController::class, 'update'])->name('update_product');

              //Delete Product
              Route::delete('/delete_product/{id}',[ProductController::class, 'destroy'])->name('delete_product');

              //Search Product
              Route::get('search',[ProductController::class, 'search'])->name('search');

      });
});

问题分析与修复方案

核心问题

  1. 中间件中存在错误的Cache-Control头设置:$response->headers->set('Cache-Control: post-check=0, pre-check=0', false);这行的键名格式错误,导致缓存头未正确生效。
  2. 登出操作的响应可能未被中间件正确处理,浏览器仍缓存了仪表盘页面。

修复步骤

1. 修正中间件的缓存头设置

修改RevalidateBackHistory.php的handle方法,合并正确的缓存头参数:

public function handle(Request $request, Closure $next)
{
    $response = $next($request);
    
    $response->headers->set('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate, post-check=0, pre-check=0');
    $response->headers->set('Pragma', 'no-cache');
    $response->headers->set('Expires', 'Sun, 02 Jan 1990 00:00:00 GMT');
    
    return $response;
}

2. 调整中间件执行顺序

在app/Http/Kernel.php中,将revalidate中间件放在web中间件组的末尾,确保它在所有业务中间件之后执行:

protected $middlewareGroups = [
    'web' => [
        // 其他中间件(如EncryptCookies、AddQueuedCookiesToResponse等)
        \App\Http\Middleware\RevalidateBackHistory::class,
    ],
];

3. 给登出路由单独加固

在web.php中给登出路由单独添加中间件,确保登出响应强制清除缓存:

Route::get('admin_signout',[AdminController::class, 'signOut'])->name('signout')->middleware('revalidate');

4. 优化登出控制器逻辑

在AdminController的signOut方法中,销毁会话后添加缓存头:

public function signOut()
{
    auth()->guard('admin')->logout();
    session()->invalidate();
    session()->regenerateToken();
    
    return redirect()->route('login')->withHeaders([
        'Cache-Control' => 'no-cache, no-store, max-age=0, must-revalidate',
        'Pragma' => 'no-cache',
        'Expires' => 'Sun, 02 Jan 1990 00:00:00 GMT',
    ]);
}

原理说明

通过设置no-cache, no-store等缓存头,强制浏览器每次请求都从服务器获取最新内容,而非读取本地缓存。登出后服务器会验证用户身份,发现未登录则跳转至登录页,此时浏览器点击返回会重新请求页面,而非展示缓存的仪表盘。

内容的提问来源于stack exchange,提问作者merchant8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 07:25:32