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

如何修复Laravel PWA登录时出现的419页面过期错误

Laravel PWA二次登录出现419页面过期问题的解决方法

问题描述

我在用Workbox开发Laravel PWA时,首次登录功能正常,但第二次登录会触发419页面过期错误。我的Service Worker代码如下:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);


const precaching = workbox.precaching;
const routing = workbox.routing;
const strategies = workbox.strategies;
const expiration = workbox.expiration;
const cacheableResponse = workbox.cacheableResponse;

precaching.precacheAndRoute([
  {url: '/login', revision: '383676'},
  {url: '/fallback.blade.php', revision: null},
  {url: '/css/auth/users.css', revision: null},
  {url: 'css/resident/resident-layout.css', revision: null},
  {url: 'images/welcome-bg.png', revision: null},
  {url: 'js/resident/resident-sidebar.js', revision: null},
  {url: 'js/app.js', revision: null},
]);

routing.registerRoute(
  ({url}) => 
    url.origin === 'https://fonts.googleapis.com' || 
    url.origin === 'https://cdn.jsdelivr.net' ||
    url.origin === 'https://code.jquery.com' ||
    url.origin === 'https://kit.fontawesome.com' ||
    url.origin === 'https://fonts.gstatic.com',
  new strategies.StaleWhileRevalidate({
    cacheName: 'links',
  })
);

routing.registerRoute(
  ({request}) => request.destination === 'image',
  new strategies.CacheFirst({
    cacheName: 'images',
    plugins: [
      new cacheableResponse.CacheableResponsePlugin({
        statuses: [0, 200],
      }),
      new expiration.ExpirationPlugin({
        maxEntries: 50,
        maxAgeSeconds: 7 * 24 * 60 * 60, // 1 week
      }),
    ]
  })
);

routing.registerRoute(
   ({request}) => request.method === 'GET',
   new strategies.StaleWhileRevalidate({
     cacheName: 'responses',
     plugins: [
       new cacheableResponse.CacheableResponsePlugin({
         statuses: [0, 200],
       }),
     new expiration.ExpirationPlugin({
         maxEntries: 50,
         maxAgeSeconds: 7 * 24 * 60 * 60, // 1 week
       }),
     ]
   }),
 );

问题原因

419错误是Laravel的CSRF令牌过期/不匹配导致的。核心问题在于你的Service Worker缓存策略:

  • 预缓存了/login页面,首次登录后浏览器保存了带有旧CSRF令牌的页面副本
  • 最后一条路由规则匹配了所有GET请求,包括/login页面,第二次访问时优先使用缓存里的旧页面,提交的CSRF令牌已经失效,触发验证错误

解决方案

1. 移除/login页面的预缓存

从precacheAndRoute数组中删除{url: '/login', revision: '383676'},确保登录页面不会被提前缓存:

precaching.precacheAndRoute([
  {url: '/fallback.blade.php', revision: null},
  {url: '/css/auth/users.css', revision: null},
  {url: 'css/resident/resident-layout.css', revision: null},
  {url: 'images/welcome-bg.png', revision: null},
  {url: 'js/resident/resident-sidebar.js', revision: null},
  {url: 'js/app.js', revision: null},
]);

2. 修改GET请求缓存规则,排除登录相关路由

调整最后一条路由规则,只缓存非认证类的GET请求,排除/login、/logout这类需要实时CSRF令牌的路由:

routing.registerRoute(
  ({request, url}) => request.method === 'GET' && 
                      !url.pathname.startsWith('/login') && 
                      !url.pathname.startsWith('/logout'),
  new strategies.StaleWhileRevalidate({
    cacheName: 'responses',
    plugins: [
      new cacheableResponse.CacheableResponsePlugin({
        statuses: [0, 200],
      }),
      new expiration.ExpirationPlugin({
        maxEntries: 50,
        maxAgeSeconds: 7 * 24 * 60 * 60, // 1 week
      }),
    ]
  }),
);

3. 为/login页面设置强制网络请求策略(可选)

如果需要更明确地控制登录页面的缓存行为,可以专门为/login路由添加NetworkOnly策略,确保每次都从服务器获取最新页面:

// 放在所有路由规则前面,确保优先匹配
routing.registerRoute(
  ({url}) => url.pathname === '/login',
  new strategies.NetworkOnly(),
);

验证步骤

  1. 清除浏览器的缓存和已注册的Service Worker
  2. 重新加载PWA应用
  3. 测试首次登录后退出,再进行第二次登录,确认419错误不再出现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 23:06:27