Laravel+Inertia生产环境Auth中间件间歇性失效求助
Laravel/Inertia应用在DigitalOcean App Platform中间件间歇性失效问题
我在DigitalOcean App Platform部署Laravel/Inertia应用,开发环境一切正常,但生产环境中,自带的Auth中间件和自定义的isActive中间件仅间歇性生效。点击链接有时可正常进入页面,有时会被重定向到登录页,刷新登录页后又能正常访问。即使用户已登录,中间件也会随机触发拦截,刷新页面可解决问题。使用的是Breeze Inertia脚手架,Auth中间件为自带组件。
自定义isActive中间件代码
class isActive extends Middleware { public function handle($request, Closure $next) { if (Auth::check()) { $userId = Auth::user()->id; $user = User::find($userId); if ($user->isActive == 'yes') { return $next($request); } } return redirect('/offer'); } }
路由配置
Route::middleware(['auth','isActive'])->group(function () { Route::get('/eromaps', [PagesController::class, 'eromaps'])->name('eromaps'); Route::get('/eromaps/desir', [DesirController::class, 'desir'])->name('desir'); Route::get('/eromaps/desir/profile', [DesirController::class, 'profile'])->name('desirProfile'); Route::get('/eromaps/plaisir', [PlaisirController::class, 'plaisir'])->name('plaisir'); Route::get('/eromaps/plaisir/profile', [PlaisirController::class, 'profile'])->name('plaisirProfile'); Route::get('/eromaps/union', [UnionController::class, 'union'])->name('union'); Route::get('/eromaps/union/profile', [UnionController::class, 'profile'])->name('unionProfile'); });
Eromaps页面示例代码
import { Link, Head } from "@inertiajs/react"; import NavBar from "../Components/NavBar"; import Footer from "@/Components/Footer"; export default function Eromaps() { return ( <main className="flex flex-col items-center min-w-screen min-h-screen bg-[url('/storage/images/map1-op.jpg')] bg-cover bg-center"> <div className=" w-10/12 min-h-screen max-w-7xl flex flex-col items-center justify-center md:justify-between relative"> <NavBar/> <div></div> <div> <h1 className="mt-32 md:mt-0 text-center text-4xl md:text-5xl font-rock">Choisis une Eromap !</h1> <div className="flex flex-col justify-center items-center gap-8 mt-12 md:grid md:grid-cols-2 md:mt-14 md:gap-x-16 md:gap-y-10"> <Link href={route("desir")}> <img className="rounded-xl w-72 shadow-xl shadow-gray-400 hover:shadow-pink-300 hover:border-2 hover:border-pink-300" src="/storage/images/desir.png" alt="" /> </Link> <Link href={route("plaisir")}> <img className="rounded-xl w-72 shadow-xl shadow-gray-400 hover:shadow-pink-300 hover:border-2 hover:border-pink-300" src="/storage/images/plaisir.png" alt="" /> </Link> <Link href={route("union")}> <img className="rounded-xl w-72 shadow-xl shadow-gray-400 hover:shadow-blue-200 hover:border-2 hover:border-teal-300" src="/storage/images/union.png" alt="" /> </Link > <Link href={route("eveil")}> <img className="rounded-xl w-72 shadow-xl shadow-gray-400 hover:shadow-blue-200 hover:border-2 hover:border-teal-300" src="/storage/images/eveil.png" alt="" /> </Link> </div> </div> <div className="mt-10"> <Footer /> </div> </div> </main> ); }
我刚结束10个月的编程培训,对此问题毫无头绪。曾尝试在控制器中添加Auth校验,当Auth()->check()失败时返回登录页,但结果相同。dd(Auth()->user())有时能获取到用户ID,有时会抛出“Attempt to read property 'id' on null”错误,刷新页面会随机出现两种情况。
排查与解决方向
1. 优先解决会话存储问题
这种间歇性认证失效,大概率是多实例部署下会话无法共享导致的。DigitalOcean App Platform如果开启多个实例,默认的文件会话驱动会让每个实例拥有独立的会话文件,请求分发到不同实例时,会话状态不一致。
- 修改
.env中的SESSION_DRIVER为redis或database:- 选用Redis的话,需要在DigitalOcean创建Redis托管实例并配置对应环境变量;
- 选用数据库的话,运行
php artisan session:table生成会话表,再执行迁移命令。
- 确认
SESSION_LIFETIME设置合理,避免会话过早过期。
2. 优化中间件代码
你的isActive中间件存在冗余查询,且未处理极端场景,可优化为:
class isActive extends Middleware { public function handle($request, Closure $next) { $user = Auth::user(); if ($user && $user->isActive === 'yes') { return $next($request); } return redirect('/offer'); } }
直接使用Auth::user()无需重复查询数据库,同时避免User::find返回null导致的报错。
3. 检查Inertia会话同步
Inertia通过XHR请求传递会话,需确保:
config/session.php中same_site设置为lax(HTTPS环境可设none,但需配合secure=true);- 前端无自定义拦截器修改请求头,保证Inertia能正常携带会话Cookie;
- 清除浏览器缓存,生产环境可能存在旧资源缓存导致的异常。
4. 核对部署配置
- 确认App Platform的实例数量:多实例部署必须使用共享会话存储(Redis/DB),文件会话无法跨实例共享;
- 检查环境变量:
APP_KEY、SESSION_DRIVER等关键配置需与开发环境一致,避免漏配或错配。
内容的提问来源于stack exchange,提问作者Velwitch
相关产品推荐
相关产品推荐

