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

Laravel 8 + Inertia.js 会话超时提交报419错误 如何跳转登录页

问题根因

你遇到的提交表单419、但GET页面可正常访问的情况,原因有两点:

  1. Laravel仅对POST/PUT/DELETE等修改类请求校验CSRF Token,会话过期后旧Token失效就会返回419错误;GET请求默认不校验CSRF,所以可以正常加载。
  2. 你没有配置全局的会话超时校验逻辑,也没有对419异常做自定义处理,所以不会自动跳转到登录页。

解决步骤

1. 修正会话基础配置

先修改.env文件的会话有效期配置,SESSION_LIFETIME单位为分钟,你要10分钟超时就改为:

SESSION_LIFETIME=10

session.php中的expire_on_close参数按需配置,设为true代表关闭浏览器就清空会话,设为false则会按设置的lifetime保留会话。配置修改后执行php artisan config:clear清除配置缓存生效。

2. 添加全局会话超时校验中间件

执行命令创建自定义中间件:
php artisan make:middleware CheckSessionTimeout

打开app/Http/Middleware/CheckSessionTimeout.php写入以下逻辑:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;

class CheckSessionTimeout
{
    public function handle($request, Closure $next)
    {
        // 排除登录、登出等公共路由,避免死循环
        if ($request->is('login') || $request->is('logout')) {
            return $next($request);
        }

        // 仅登录用户需要校验会话超时
        if (Auth::check()) {
            $lastActivity = Session::get('last_activity');
            $timeout = config('session.lifetime') * 60; // 分钟转秒

            // 超时则清空会话跳转登录
            if (time() - $lastActivity > $timeout) {
                Auth::logout();
                Session::flush();
                return $request->inertia() 
                    ? redirect()->route('login')->with('message', '会话已超时,请重新登录')
                    : redirect()->route('login');
            }

            // 每次请求更新最后活动时间
            Session::put('last_activity', time());
        }

        return $next($request);
    }
}

打开app/Http/Kernel.php,将中间件注册到web中间件组,放在StartSession之后:

protected $middlewareGroups = [
    'web' => [
        // ... 其他原有中间件
        \Illuminate\Session\Middleware\StartSession::class,
        \App\Http\Middleware\CheckSessionTimeout::class, // 新增这行
        // ... 其他原有中间件
    ],
];

3. 自定义处理419 CSRF异常

打开app/Exceptions/Handler.php,修改register方法拦截Token过期异常:

use Illuminate\Session\TokenMismatchException;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;

public function register()
{
    $this->renderable(function (TokenMismatchException $e, $request) {
        // 先清空无效会话
        Auth::logout();
        Session::flush();

        // Inertia异步请求返回重定向响应
        if ($request->inertia()) {
            return redirect()->route('login')->with('message', '会话已超时,请重新登录');
        }

        // 普通表单请求直接跳转登录
        return redirect()->route('login')->withErrors(['message' => '会话已超时,请重新登录']);
    });
}

4. 前端适配(可选,体验更流畅)

在前端入口文件resources/js/app.js中添加全局响应拦截,遇到419状态直接跳转登录:

import { Inertia } from '@inertiajs/inertia'

Inertia.on('error', (event) => {
  if (event.detail.response.status === 419) {
    window.location.href = '/login'
  }
})

内容的提问来源于stack exchange,提问作者Achraf Ben Soltane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 03:36:08