如何修复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(), );
验证步骤
- 清除浏览器的缓存和已注册的Service Worker
- 重新加载PWA应用
- 测试首次登录后退出,再进行第二次登录,确认419错误不再出现
内容的提问来源于stack exchange,提问作者Furukuku
相关产品推荐
相关产品推荐

