はじめに
Laravelのセッション管理(認証機能)についてまとめてみました。
まず、用語
Cookie(クッキー)
-
テキスト情報
-
HTTPレスポンス
- Set-CookieヘッダーフィールドにCookieフィールドに「Set-Cookie: クッキー名=値; 属性名=属性値;属性名=属性値 …」形式で挿入される
-
HTTPリクエスト
- Cookieフィールドに「Cookie: クッキー名=値; 属性名=属性値;属性名=属性値 …」形式で挿入される
クッキーとはHTTPレスポンス、HTTPリクエストに設定されるクッキー名=クッキー値の名前と値の組のテキスト情報のこと
- 値の後に属性が続く場合は、「;」(半角のセミコロン)で区切られて並ぶ。
- 属性値は必須ではない
- クッキーの送信する適用範囲をpath属性、domain属性で指定する
- 複数指定する場合。例レスポンス。複数のSet-Cookiフィールドにクッキーを指定する。リクエストも同様。
- Set-Cookie: クッキー名1=値;
- Set-Cookie: クッキー名2=値;
Cookie(クッキー)保存場所
- ローカルの端末内にあるテキストファイルにクッキーが保存される
- いろんなクッキーの説明をみると、この領域もクッキーと呼んだり、呼ばなかったりしているように見える。
クッキーをどう使うのか
HTTP通信は状態を維持できない(初回のHTTP通信と、次のHTTP通信が同じユーザであることを判別できない)のでクッキーを使うことで(クッキーに通信を識別する情報を保持して)状態を維持できるようになる(ユーザーを判別できるようになる)。
セッションIDとセッション管理
-
セッションIDとは、Webアプリケーションなどで、通信中の利用者を識別して行動を捕捉し、利用者ごとに一貫したサービスを提供するために付与される固有の識別情報。そのような仕組みをセッション管理という。
-
意味合い的にはユーザーを識別するためのラベル(受付番号)のようなもので、ランダムな文字列(例:jZ6VkVkVUIyNHJPNSIsIm...)
-
セッションIDはユーザーIDを暗号化したものではない
クッキーにセッションIDをのせて、クライアント、サーバー間で通信することでユーザーを識別できるようになる
クッキーを利用したセッション管理の流れ
- クライアント: ログインします(HTTPリクエスト)
- サーバー : OK-。HTTPレスポンスにset-Cookie: key=value (valueにセッションIDが入る)を設定してクライアントに送信
- set-Cookieとはクッキー(クッキー名=クッキー値)を保存してください&次回以降はHTTPリクエストにクッキー(クッキー名=クッキー値)を付加して情報も送ってくださいという命令
- クライアント: 次回以降はクッキー名=クッキー値がHTTPヘッダフィールドに記載されたHTTPリクエストをサーバに送付する
Lavavelのセッション
Laravelバージョン
Laravel Framework 5.8.35
Laravelでのセッション管理
config/auth.phpでLaravelでセッション管理する場合の操作方法を決めます。操作方法にはfile
やcookie
、database
など幾つかの方式をサポート。デフォルトだとfile方式でセッションを管理するようになっています。
7 /*
8 |--------------------------------------------------------------------------
9 | Default Session Driver
10 |--------------------------------------------------------------------------
11 |
12 | This option controls the default session "driver" that will be used on
13 | requests. By default, we will use the lightweight native driver but
14 | you may specify any of the other wonderful drivers provided here.
15 |
16 | Supported: "file", "cookie", "database", "apc",
17 | "memcached", "redis", "dynamodb", "array"
18 |
19 */
20
21 'driver' => env('SESSION_DRIVER', 'file'),
Laravelのセッション管理
Laravelでは幾つかの方法でセッションを管理することが分かりました。今度はセッション管理がCookieの場合とfileの場合にどうやってHTTPアクセスからユーザーを識別しているのか調べてみました。
セッション管理がfileの場合
- ユーザーがサーバにログインした際にサーバ側では
storage/framework/sessions/セッションID
のファイルを作成
して中身にはusersテーブルの主キー=users.idを記入 - サーバからのHTTPレスポンスにはSet-Cookieヘッダに暗号化されたセッションID(クッキー)が記述されていて、クライアントは端末に暗号化された
セッションID
(クッキー)を保存 - 以降、ユーザのHTTPリクエスト毎にリクエストのCookieヘッダからクッキー(下記画像のvalue)の
セッションID
をとりだして同じstorage/framework/sessions/セッションID
ファイルを探し出し、中身のusersテーブルの主キーを見て、どのユーザーからのアクセスなのかを理解している。
下記画像が実際のクッキーの値valueに暗号化されたセッションIDが入っている
ユーザの識別情報があるstorage/framework/sessions/セッションIDの中身
.
.
{s"login_xxx_暗号化";i:ユーザーID(usersテーブルの主キー);} ← これでユーザーを特定する
暗号化されたセッションIDを復号
Crypt::decryptString("eyJpdiI6InFQ.........");
=> "M9fH83wgHK6Nze..."
↑のセッションIDの値がファイルとして作成されている
ll storage/framework/sessions/M9fH83wgHK6Nze...
セッション管理がCookieの場合
nameが暗号化なしのセッションIDになっていて、valueに上記fileセッション管理の時のstorage/framework/sessions/セッションIDファイルの中身がそのまま書かれている
valueの中身を確認してみた。暗号化されているのでdecryptStringで復号すると上記fileセッション管理の時のstorage/framework/sessions/セッションIDファイルの中身がそのまま書かれていた。
>>> Crypt::decryptString("eyJpdiI6IlNiUWFLN1l4M3JKWmtoSlVxQWV0eEE9PSIsInZhbHVlIjoiUU9NdjE4V2VsYUhFMGJmc1FwUDZHWXpjMkYzNGphRHg3cTc2M1l1QTArcTJZVXdFczlvUnYzaXdPMDZ4MFlPYmh2NDlcL3lY・・・");
=> "{"data":"a:5:{s:6:\"_flash\";a:2:・・0:\"xxxxxxxx\";s:3:\"url\";xxxx:{}s:9:\"_previous\";a:
1:{s:3:\"url\"xxxx:\"http:\/\/xxxxxxxx";}s:5s"login_xxx_暗号化";i:ユーザーID(usersテーブルの主キー);","expires":1572584018}"
ユーザーを識別する仕組みはfileの時と同様で、クッキーを取り出して複合化して、usersテーブルの主キーをみてどのユーザからのアクセスか判定している。
クッキーの中に情報そのものをか格納するのか、セッションIDだけを格納するのかが大きな違い