Laravel Session::getId() 在登录和注销时不同

Laravel Session::getId() is different on login and logout

我有 table user_logins 来维护关于用户

的多个登录信息

table user_logins 的结构:

    'session_id',
    'user_id',
    'ip_address',
    'user_agent',
    'browser_name',
    'location',
    'login_at',
    'is_active'

我有 UserEventSubscriber 具有 2 个功能的侦听器,如下所示:

public function handleUserLogin($event) {
     UserLogin::create([
        'session_id'=>Session::getId(),
        ...
     ]);
}   

我在 handleUserLogin 函数中得到 Session::getId() = mpT6RDsl54JExkejrqf3fnYiFLzbR2pTb2qfNHBe

现在,当用户注销时,我想更新/删除 user_logins table 中的 table 条目,其中 session_id = Session::getId()

 public function handleUserLogout($event) {
        dd(Session::getId());
        //UserLogin::where('session_id',Session::getId())->delete();
 }

在 handleUserLogout 函数上我得到一个不同的会话 ID

Session::getId() qLYngAx1Vs8VBhxm0oCKZO3fDwun02UEXRyDm0Hi 所以我无法 update/delete 进入 user_logins table

我已经看到 sessions table 的 ID qLYngAx1Vs8VBhxm0oCKZO3fDwun02UEXRyDm0Hi 与我在注销功能上获得的 ID 相同。

所以我的问题是为什么我在用户登录功能上得到不同的会话 ID?我应该怎么做才能在 handleUserLogin 和 handleUserLogout 函数中使用 Session::getId() 获得相同的会话 ID。

我发现,需要从 Auth/LoginController

中的 AuthenticatesUsers 覆盖 sendLoginResponse

$request->session()->regenerate() 登录后生成新的会话 ID,所以如果您想获得与以前相同的 ID,请注释掉该行。

 protected function sendLoginResponse(Request $request)
    {
        // $request->session()->regenerate();   <-- this line is generating new session after user login 
        $this->clearLoginAttempts($request);

        return $this->authenticated($request, $this->guard()->user())
                ?: redirect()->intended($this->redirectPath());
    }

先生,您是我的英雄。我遇到了同样的问题,但是当我使用 Fortify 时,我需要注释掉的代码在以下文件中:

/vendor/laravel/fortify/src/Actions/PrepareAuthenticatedSession.php

handle函数的第一行是:

$request->session()->regenerate();

注释掉,验证后会话 ID 不会重新生成。

对于未来的 Google 员工,这也导致在通过ajax请求。

我在处理 Illuminate\Auth\Events\Login 事件时还需要旧会话 ID。 找到两个额外的选项。

  • 从会话cookie中获取;例如request()->cookies()->get(session()->getName()),
  • 或收听较早的事件,例如Illuminate\Auth\Events\Attempting 并将当前 Id 存储在会话中的某处。这样您就可以在 Login 事件处理程序中检查它。