🗝️

CookieとSessionをLaravelのコード使って理解する!!

2023/05/14に公開

最初に

この記事はLaravelにおけるSession管理について述べてる記事です。

また、今回はSession管理にRedisを使用しています。

Cookieで管理する場合は、少し内容が異なるので注意してください。

CookieとSession

CookieとSessionと聞いて、うわーって思う人もいるかと思うが、これを読んだら必ず理解できると思う。

多くは、Cookieはクライアントに保存するデータ、Sessionはサーバー側で保存するデータなどの表現があると思うが、もう少し噛み砕くと下記の通りである。

LaravelにおけるCookieとSession

laravelではアプリケーションにリクエストを送ったタイミングで、Cookieにlaravel_sessionというsession名でsessionIdが値として暗号化され、保存される。(※これはデフォルトの機能)

それは下記のStartSessionクラスが自動でCookieにSessionIdを保存してくれてるからだ。

Kernel

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,
],

試しに下記をコメントアウトすると、

Kernel

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を暗号化する役割を担っている。

Kernel
    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