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

如何配置Laravel避免自动延长认证会话并强制其到期?

这个问题我之前也折腾过,Laravel默认的会话机制确实是每次用户发起请求就自动续期,要实现「不管用不用都到点过期」的效果,得从会话的过期逻辑入手,下面给你两个可行的方案,按需选就行:

方案一:登录时设置固定会话过期时间(推荐)

这种方法针对性强,只对用户登录后的会话生效,逻辑也更清晰。

  1. 找到你的登录控制器(默认是app/Http/Controllers/Auth/LoginController.php),如果没有authenticated方法,就新增一个:
protected function authenticated(Request $request, $user)
{
    // 获取配置文件里的会话有效期(分钟)
    $lifetime = config('session.lifetime');
    // 计算固定过期时间:当前时间 + 设定的有效期
    $expireAt = now()->addMinutes($lifetime);
    // 把过期时间存入会话
    $request->session()->put('expire_at', $expireAt->timestamp);
}
  1. 创建一个专门检查会话过期的中间件:
php artisan make:middleware CheckSessionExpiration
  1. 打开生成的app/Http/Middleware/CheckSessionExpiration.php,修改handle方法:
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;

public function handle(Request $request, Closure $next)
{
    if ($request->session()->has('expire_at')) {
        $expireAt = Carbon::createFromTimestamp($request->session()->get('expire_at'));
        // 如果当前时间已超过过期时间,强制登出并销毁会话
        if (now()->gte($expireAt)) {
            Auth::logout();
            $request->session()->invalidate();
            $request->session()->regenerateToken();
            
            return redirect()->route('login')->with('message', '会话已过期,请重新登录');
        }
    }

    return $next($request);
}
  1. 把这个中间件注册到app/Http/Kernel.php的web中间件组里,放在StartSession之后:
protected $middlewareGroups = [
    'web' => [
        // ...其他中间件
        \App\Http\Middleware\StartSession::class,
        \App\Http\Middleware\CheckSessionExpiration::class,
        // ...其他中间件
    ],
];

这样用户登录后,会话就有了固定的过期时间,不管之后有没有操作,到点都会被强制登出。

方案二:全局禁用会话自动续期

如果想要所有会话(包括未登录用户的会话)都遵循固定过期规则,可以用这个方法:

  1. 先修改config/session.php的基础配置:
return [
    // ...其他配置
    'lifetime' => 120, // 你想要的固定有效期(分钟)
    'expire_on_close' => false,
];
  1. 自定义StartSession中间件,重写会话续期逻辑:
    创建app/Http/Middleware/StartSession.php,继承框架的原中间件:
namespace App\Http\Middleware;

use Illuminate\Session\Middleware\StartSession as BaseStartSession;

class StartSession extends BaseStartSession
{
    // 重写刷新会话过期时间的方法,直接空实现
    protected function refreshSessionExpiration($request)
    {
        // 注释掉父类的自动续期逻辑,让会话过期时间不再随请求刷新
        // parent::refreshSessionExpiration($request);
    }
}
  1. 在app/Http/Kernel.php里替换原有的StartSession中间件:
protected $middlewareGroups = [
    'web' => [
        // ...其他中间件
        // \Illuminate\Session\Middleware\StartSession::class,
        \App\Http\Middleware\StartSession::class,
        // ...其他中间件
    ],
];

修改后,所有会话的过期时间都是创建时的时间加上lifetime,不会因为后续请求延长,到点自动失效。

注意事项
  • 如果你用的是database或redis会话驱动,要确保存储介质的过期时间和配置同步;
  • 测试时可以把lifetime设为1分钟,快速验证效果;
  • 方案一适合仅针对登录用户会话的场景,方案二更适合全局会话管控。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:31:30