Edited at

LaravelのSession管理について理解しておきたいところ


環境


  • Laravel5.8で確認しました。バージョンによっては仕様は変わる可能性があるので必ず正しいとは言えません。


先に理解をしたほうが良いこと


Laravelは独自のSession管理を行っている


SessionのIDは個々人のCookieに保存されている(session.cookieの値=>Laravel上で用意した40文字のランダム文字列)

ここを勘違いしていると悩ましいことになる。

Laravelは独自のSessionの仕組みを持っているがIDはCookie上で管理している。


認証のGuardすべてがセッションに関連があるわけではない

認証のGuardにSessionだったりTokenがあるから認証のときに関わりがあるのではと感じてしまうが、SessionGuardのみManagerから情報を貰っている。

Tokenの場合は基本的にAPIであり、セッションを開始するMiddlewareは実行されない。


Session(中身)の読み出され方


接続の部分

SessionはSessionManagerによって管理がされている。SessionDriverはconfig.session.driverにセットしているもの。

SessionManager


SessionDriver(SessionHandler)

あくまでもSessionManagerはSessionDriverを作成して接続を保証しているだけ。ここでStoreも作成しているけど、Readはまだしてない。(Storeがコンストラクタでidをセットしている処理があるので勘違いしやすいが、これは初回のセッション用である)


読み出しに関して

実際にSessionをReadしているのはIlluminate\Session\Middleware\StartSession

getSessionメソッドで、SessionManagerからSessionDriverを取得しCookieに保存されている値をセットしてstartしている。(Storeに既存ユーザーのIdをセットしているのはここ)

public function getSession(Request $request)

{
return tap($this->manager->driver(), function ($session) use ($request) {
$session->setId($request->cookies->get($session->getName()));
});
}

protected function startSession(Request $request)

{
return tap($this->getSession($request), function ($session) use ($request) {
$session->setRequestOnHandler($request);

$session->start();
});
}


セッションの書き込みについて

これに関してもStartSessionミドルウェアにかかれている。

LaravelのSessionはレスポンスを返すまで保存されないとよく言われてるのはこれ。

特に言うこともない。。。


public function handle($request, Closure $next)
{
if (! $this->sessionConfigured()) {
return next($request);
}

// If a session driver has been configured, we will need to start the session here
// so that the data is ready for an application. Note that the Laravel sessions
// do not make use of PHP "native" sessions in any way since they are crappy.
$request->setLaravelSession(
$session = $this->startSession($request)
);

$this->collectGarbage($session);

$this->storeCurrentUrl($request, $session);

$this->addCookieToResponse(
$response = $next($request), $session // ここで$nextを実行してレスポンスを貰っている
);

// Again, if the session has been configured we will need to close out the session
// so that the attributes may be persisted to some storage medium. We will also
// add the session identifier cookie to the application response headers now.
$this->manager->driver()->save(); // セッションが保存されるのはそのレスポンスを貰った後

return $response;
}


さいごに

これを調べることになったのはGuardの存在でした。

Guardのセッション管理方法を変更する必要があり、そこで行き詰まったのでとりあえず親の方を見ていこうと。

正直よい知識を得れたと思います。SessionHandlerやSessionManagerがどうしているか理解できたことが今回の一番の収穫です。