CookieとSessionをLaravelのコード使って理解する!!
最初に
この記事はLaravelにおけるSession管理について述べてる記事です。
また、今回はSession管理にRedisを使用しています。
Cookieで管理する場合は、少し内容が異なるので注意してください。
CookieとSession
CookieとSessionと聞いて、うわーって思う人もいるかと思うが、これを読んだら必ず理解できると思う。
多くは、Cookieはクライアントに保存するデータ、Sessionはサーバー側で保存するデータなどの表現があると思うが、もう少し噛み砕くと下記の通りである。
LaravelにおけるCookieとSession
laravelではアプリケーションにリクエストを送ったタイミングで、Cookieにlaravel_sessionというsession名でsessionIdが値として暗号化され、保存される。(※これはデフォルトの機能)
それは下記のStartSessionクラスが自動でCookieにSessionIdを保存してくれてるからだ。
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class, ※これ!!
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\HandleInertiaRequests::class,
\Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
],
試しに下記をコメントアウトすると、
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
// \Illuminate\Session\Middleware\StartSession::class, ※コメントアウト
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\HandleInertiaRequests::class,
\Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
],
ここまででサーバー側のSessionIdをクライアント側のCookieに保存されている挙動について理解できたと思う。
次にSessionIdというものが何かを見ていく。
SessionIdとは??
先ほど、Cookieに対してSessionが保存できていることは確認できたと思う。
次に実際にサーバー側で保存したCookieのSessionIdが受け取れているのかを確認する。
結果は下記の通りである。なんだか受け取れてはいるが、値が同じものではないため、確信を持って受け取れてるとは言い難い。
左側はLaravelで下記のコマンドをデバッグした時の結果
Cookie::get(),
重要なのが、SessionIdが暗号化されているということ、次に下記の、EncryptCookiesをコメントアウトする
実はこのクラスの役割は、Cookieに保存するときにsessionIdを暗号化する役割を担っている。
protected $middlewareGroups = [
'web' => [
// \App\Http\Middleware\EncryptCookies::class, ※コメントアウト
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\HandleInertiaRequests::class,
\Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
],
これで再度確認すると、Cookieに保存したSessionIdが正しく見ることができ、サーバー側でも同じ値を取得できていることがわかる。
つまり、リクエスト時に、SessionIdをサーバー側で暗号化して発行し、それをクライアント側で保存している。
ここまでがCookieとSessionの仕組み
認証におけるCookieとSession
今までのことを使って、認証の場合どうなってるのかを下記で説明する。
簡単にいうと、認証した時に、sessionIdをクライアント側で保存させ、そのタイミングで、sessionIdをもつDriverにログイン情報を保存させている。
実際にログイン前とログイン後で試した結果が下記
▼ログイン前
▼ログイン後
実際に下記のコマンドをLaravel内で実行すると、session情報が取得できる
dd(session());
重要なのは、attributesの中に、_token以外にlogin_の情報が保存されていることである。(今回はUlidを保存してるので、Laravelのデフォルト機能だと1などが保存されると思う)
これがあるということは、ログイン成功時にSessionに保存できたということになる。
認証後
ここまできたら、あとは簡単で、クライアントからリクエスト時にCookie情報(SessionId)をサーバー側に送ってくるので
認証後はそのSessionidの中に含まれている、Session情報を取得してUserが認証ずみかを判定すればOK
なので、Sessionが切れるというのは、SessionIdに紐づいていたattributesが消えるというより、
SessionIdそのものが無効になって、attributesがなくなったという捉え方かもしれない。
Discussion