はじめに
こんにちは、開発エンジニアのシカタです。
今回は、開発を担当するプロダクトでアーキテクチャを刷新することになり、Laravelの検討したときのお話です。
アーキテクチャの刷新だけにたくさんの課題がありましたが、その中でも今回はセッションのことについて書きます。
Laravelをやってみようとか、既存プロダクトにLaravelを載せてみたいなーと思ってる人の心に刺されば幸いです。
背景
既存の運用中プロダクトの一部サブシステムを、新アーキテクチャで構築し直すプロジェクトがスタートしました。
一気にリリースすると影響が大きすぎるので、一部の機能から徐々にリリースしていく方針です。
現在ノンフレームワークのため、せっかく新しくするならフレームワークを採用したい…
ということで、Laravelを検討してみることになりました。
既存プロダクトのノンフレームワークな世界と、Laravelで新しく作る世界を共存させることを検討する必要があり、フレームワークの機能を活用することを目指していますが、たくさんの課題が出てきました。
- アーキテクチャどうしよう…
- Laravelを活かすにはどういうアーキテクチャで共存させるのが良いのか…
- 既存プロダクトとLaravelでどうやってセッション共有しよう…
- 認証周りとかどうするのが良いんだろう…etc
今回は課題の中からセッションについて取り上げます。
Laravelのセッション管理について
まず、Laravelの基本的なセッション管理についてです。
セッションドライバについて
Laravelでは、file、cookie, DBなどでセッション情報を管理することができます。
config/session.php
にセッションに関する設定は記載されています。
config/session.php
return [
/*
|--------------------------------------------------------------------------
| 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'),
:
:
]
セッションの操作
Laravelでセッションの操作を行うには、Requestインスタンス
、sessionヘルパ
、Sessionファサード
を使う方法があります。
基本操作に大きな違いはありません。
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Session; class HogeFunction extends Controller { /** * @param Request $request * @return Response */ public function hogee(Request $request) { /* セッションから1つデータを取得する */ // Requestインスタンス $value = $request->session()->get('key'); // Sessionヘルパ $value = session('key'); // Sessionファサード $value = Session::get('key'); /* セッションの値をすべて取得する */ // Requestインスタンス $values = $request->session()->all(); // Sessionヘルパ $values = session()->all(); // Sessionファサード $values = Session::all(); /* セッションに値を保存する */ // Requestインスタンス $request->session()->put('key', 'value'); // Sessionヘルパ session(['key' => value]); // Sessionファサード Session::put('key', 'value'); /* セッションに値を削除する */ // Requestインスタンス $request->session()->forget('key'); // Sessionヘルパ session()->forget('key'); // Sessionファサード Session::forget('key'); /* セッション中に値が存在することの確認(existsはnullでもTrueを返す) */ // Requestインスタンス $request->session()->has('key'); $request->session()->exists('key'); // Sessionヘルパ session()->has('key'); session()->exists('key'); // Sessionファサード Session::has('key'); Session::exists('key'); } }
セッションの共有を検討してみた
既存プロダクトとLaravelでセッションを共有させる方法を検討してみました。
既存プロダクトがDBでセッション管理されているため、今回はLaravelでもDBを用いたセッション管理を前提に考えています。
また、既存プロダクトではセッション周りは純粋なPHPで実装していますが、Laravelのセッション周りは独自実装になっています。
どこかでsession_start();
しておけばいい感じになるだろう、というわけにはいきません。
この違いも少し厄介なポイントです。
LaravelでDBを使ってセッション管理する
LaravelでDBを使いセッション管理する場合は、以下のようなテーブルを作成する必要があります。
Schema::create('sessions', function ($table) { $table->string('id')->unique(); $table->foreignId('user_id')->nullable(); $table->string('ip_address', 45)->nullable(); $table->text('user_agent')->nullable(); $table->text('payload'); $table->integer('last_activity'); });
以下のように設定しておくと、セッション管理に使用するテーブルと認識されます。
config/session.php return [ /* |-------------------------------------------------------------------------- | 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', 'database'), : : /* |-------------------------------------------------------------------------- | Session Database Table |-------------------------------------------------------------------------- | | When using the "database" session driver, you may specify the table we | should use to manage the sessions. Of course, a sensible default is | provided for you; however, you are free to change this as needed. | */ 'table' => 'sessions', : : ]
セッション共有の検討
既存プロダクトで使用しているテーブルを使用するか、Laravelに合わせたテーブルを使用するのか…他にもいくつか選択肢がありました。
少なくとも、Laravelのセッション機能を活用しようと思うと、
LaravelでDBを使ってセッション管理する際にテーブル定義の通り作成が必要となるようです。
Laravelのセッションが確立するまでの独自実装を追ってみると、以下にたどり付きました。
Illuminate/Session/DatabaseSessionHandler.php
ここを見る限りは指定されているテーブル定義前提で動くような実装になっています。
セッション管理のテーブルやセッション周りの実装が似ていれば移行前提で検討できるかもしれませんが、そうでなければ難しいです…。
よって、LaravelデフォルトのDBのセッションドライバのままでは、既存プロダクトとのセッション共存は困難であることがわかりました。 しかし、Laravelにはカスタムセッションドライバという仕組みがあり独自のセッションドライバを実装できます。
Laravelのカスタムセッションドライバ
以下のように、SessionHandlerInterface
を実装することで独自のセッションドライバの作成が可能です。
<?php namespace App\Extensions; class CustomSessionHandler implements \SessionHandlerInterface { // open: ファイルベースでなければ空でOK public function open($savePath, $sessionName) {} // openと同様 public function close() {} // セッションの読み込み処理($sessionIdに紐づくセッションデータの取得) public function read($sessionId) {} // セッションの書き込み処理($sessionIdに紐づく$dataの書き込み) public function write($sessionId, $data) {} // セッションの読み込み処理($sessionIdに紐づくセッションデータの削除) public function destroy($sessionId) {} // セッションの読み込み処理($lifetimeを超えたセッションデータの削除) public function gc($lifetime) {} }
次に、作成したカスタムセッションドライバの登録方法についてです。
Session
ファサードのextend
メソッドで登録することができます。
ServiveProvider
のboot
メソッドで上記メソッドを呼ぶことでカスタムセッションドライバの登録ができます。
既存のAppServiceProvider
またはセッション用に作成したServiceProvider
から呼び出します。
下記はServiceProvider
から呼び出す例です。
<?php namespace App\Providers; use App\Extensions\CustomSessionHandler; use Illuminate\Support\Facades\Session; use Illuminate\Support\ServiceProvider; class SessionServiceProvider extends ServiceProvider { /** * 全アプリケーションサービスの登録 * * @return void */ public function register() { // } /** * 全アプリケーションサービスの初期起動 * * @return CustomSessionHandler */ public function boot() { Session::extend('custom', function ($app) { // Return implementation of SessionHandlerInterface... return new CustomSessionHandler; }); } }
最後に、作成したカスタムセッションドライバをconfig/session.php
で設定すると、使用できるようになります。
config/session.php
return [
/*
|--------------------------------------------------------------------------
| 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', 'custom'),
:
まとめ
Laravelのセッションについてまとめてみました。
既存のプロダクトとLaravelでセッションをさせる方法は現在検討中なので、
また次の機会に実際に実装したカスタムセッションドライバなどは紹介できればと思います。
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com