【PHP】Laravelのセッション管理を勉強する

#この記事について
[この記事](https://qiita.com/666mikoto/items/f9462235a5646669f7e5)で認証機能をセットアップしてアカウント登録、ログインができるようになりました。
ログイン時にセッション情報がLaravelでどのように管理されているか、ちょっと勉強してみましょう。

#環境
OS：Windows10 Home
PHP：7.4.15（XAMPP)
Laravel：6.20.16

#セッション管理の種類
Laravel6のセッションについては、[こちら](https://readouble.com/laravel/6.x/ja/session.html)のページで記載されています。


設定は```.env```と```config/session.php```に記述されていています。

```:.env
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
```

```PHP:config/session.php
    /*
    |--------------------------------------------------------------------------
    | Default Session Driver
    |--------------------------------------------------------------------------
    |
    | This option controls the default session "driver" that will be used on
    | requests. By default, we will use the lightweight native driver but
    | you may specify any of the other wonderful drivers provided here.
    |
    | Supported: "file", "cookie", "database", "apc",
    |            "memcached", "redis", "dynamodb", "array"
    |
    */

    'driver' => env('SESSION_DRIVER', 'file'),


```

デフォルトのドライバーは```file```になっていて、他によく利用されるのは```database```でしょうか。

#fileでの管理
デフォルト設定は```file```になっていて、セッション情報が```storage/framework/sessions```にて管理されます。
ファイル名がセッションIDになっていて、この値を暗号化しものがcookieの値にとして設定されることになります。
ファイルの中身を見てもあまり分かりません...

```
a:4:{s:6:"_token";s:40:"4usky7k5qOVADHV9TokTtur7ZP9bhOTAN0Jq2rFn";s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}s:9:"_previous";a:1:{s:3:"url";s:26:"http://127.0.0.1:8000/home";}s:50:"login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d";i:1;}
```
ただ、最後の```i:1```はログインしているアカウントのIDを指しています。

ちなみにcoockieの値を```php artisan tinker```を使って、以下の方法で復号するとセッションIDを知ることができます。


```
Crypt::decryptString("(cookieのvalue)");
```

セッション単位でファイルが増えていくので、アクセスが多い場合はfileでの管理はあまりお勧めできないかと思います。
テスト環境とかであれば特に気にすることはないと思いますが。

#databaseでの管理
Driverをdatabaseにする場合、```.env```と```config/session.php```ファイルを修正します。

```:.env
SESSION_DRIVER=database
```

```PHP:config/session.php
    'driver' => env('SESSION_DRIVER', 'database'),
```

またDB上で管理するために、セッション管理用のテーブルを作成する必要があります。
migrationファイルは以下のコマンドで作成することができます。

```
php artisan session:table
```

作成されたファイルはこちら

```PHP:database/migration/yyyy_mm_dd_hhmmss_create_sessions_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateSessionsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('sessions', function (Blueprint $table) {
            $table->string('id')->unique();
            $table->unsignedBigInteger('user_id')->nullable();
            $table->string('ip_address', 45)->nullable();
            $table->text('user_agent')->nullable();
            $table->text('payload');
            $table->integer('last_activity');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('sessions');
    }
}
```
このmigrationファイルをmigratheします。

```
php artisan migrate
```
これでDBに```sessions```テーブルが生成されます。

実際にサイトにアクセスする前に.envファイルを更新しているので、キャッシュのクリアをします。

```
php artisan cache:clear
```
この後、Lravelサーバーを立ち上げ直し、アクセスすると```sessions```テーブルに値が格納されます。

```
MariaDB [demo]> select * from sessions\G
*************************** 1. row ***************************
           id: hzFDAVivjl24e70SQxMuqzDjUh1yDfbTmghEXkEq
      user_id: 1
   ip_address: 127.0.0.1
   user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36
      payload: YTo0OntzOjY6Il90b2tlbiI7czo0MDoicnpWNG9IT2pRZmRxUmJrc2Y0dE9mNUc2dGN3cEFjMEtWbEo1U2hENSI7czo2OiJfZmxhc2giO2E6Mjp7czozOiJvbGQiO2E6MDp7fXM6MzoibmV3IjthOjA6e319czo5OiJfcHJldmlvdXMiO2E6MTp7czozOiJ1cmwiO3M6MjY6Imh0dHA6Ly8xMjcuMC4wLjE6ODAwMC9ob21lIjt9czo1MDoibG9naW5fd2ViXzU5YmEzNmFkZGMyYjJmOTQwMTU4MGYwMTRjN2Y1OGVhNGUzMDk4OWQiO2k6MTt9
last_activity: 1613659044
1 row in set (0.001 sec)
```
こんな感じです。
```id```はセッションIDですね。
```user_id```はそのままユーザーIDです。ここがNULLだとログインしていないことになります。
他にもIPアドレスやユーザーエージェントの値も格納されています。
```payload```にはその他色々な情報が格納されていますが、暗号化されています。
```last_activity```は最後に行動した日時がUNIX時間で格納されています。

ファイルの時より少し視覚的に分かりやすいので、こちらの方が管理しやすいかと思います。
SQLで操作できるのも良い点ですね！

#その他
上記```file```と```database```以外にもDriverはあります。
例えば、```cookie```は、cookieに値がそのまま入るイメージですかね？
cookieのnameに暗号化なしのセッションIDが格納され、valueにファイルで格納されていた中身がそのまま格納される感じです。

セッションをRedisで管理したい場合は```redis```で設定することになります。
この場合は、```config/database.php```のRedis設定をする必要があります。

#最後に
今回はセッション情報がどのように管理されているかを簡単にまとめてみました。
セッション情報の使用はまた機会があればまとめてみようと思います。