Laravel AuditingでRESTful API(JWT認証)をばっちり監視
記事の目的
本記事では、Laravel 10を使用し、JWT認証を取り入れたステートレスなAPI実装における、
Laravel Auditingの取り扱い方について解説します。
Laravel Auditingとは
Laravel Auditingはデータベースのレコードが作成、更新、削除されるたびに、これらの変更を自動的に記録してくれます。これにより、後で何が起こったかを正確に確認することができるので、バグの追跡やセキュリティ監査にも役立ちます。
セットアップ方法
インストール
composerを使用します。
composer require owen-it/laravel-auditing
プロバイダーに追加
インストール後にconfig/app.php
にproviderを追加してください。
'providers' => [
// ...
+ OwenIt\Auditing\AuditingServiceProvider::class,
// ...
],
設定ファイル作成
プロバイダを追加後、以下コマンドで設定ファイルを作成します。
php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="config"
テーブルを作成
保存先のマイグレーションファイルを作成します。
php artisan vendor:publish --provider "OwenIt\Auditing\AuditingServiceProvider" --tag="migrations"
auditsテーブルのuser_idがintegerで定義されているので、必要に応じて変更してください。
class CreateAuditsTable extends Migration
{
public function up()
{
- $table->unsignedBigInteger($morphPrefix . '_id')->nullable();
+ $table->string($morphPrefix . '_id')->nullable();
});
}
}
今回user_id(jwtのsub)はstring型なので上記のように変更します。
そののちにartisan
コマンドを実行し、audits
テーブルを作成してください
php artisan migrate
監視手順
セットアップが完了したら、次は実際にデータを監視する方法に入りますが、ステートレスなAPIの実装において、公式ドキュメント通りの実装を行うと、CRUD実行後のauditsテーブルには、user_idが格納されません。そのため、少々工夫が必要になります。
$requestにユーザーIDを付加
ミドルウェアを用いてJWT認証を行いますが、JWTをデコードした際に格納されるsub
と呼ばれるユーザー識別子をHTTPリクエストオブジェクトである$requestに付加します。
$request->attributes->add(['jwt_sub' => $decode->sub]);
JWT認証のほかにも、ログイン状態でないが、操作したユーザーのIDを格納したい場合には上記のように、リクエストに属性を付加してください。
トレイトを作成
トレイトは、複数のクラスで共通の機能を再利用したい場合に役立つ仕組みです。今回は、Auditingのトレイトにデフォルトで定義されてあるtransformAudit
というメソッドをオーバーライドする必要があるので、下記のようなカスタムトレイトを作成します。
<?php
namespace App\Traits;
trait AuditableCustom
{
public function transformAudit(array $data): array
{
$data['user_id'] = request()->attributes->get('jwt_sub');
return $data;
}
}
先ほどrequestに設定した属性を取得し、user_idに格納します。
監視設定
データの監視を行う際は、対象のModelに対して下記のような設定を加えます。
具体例
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
+ use OwenIt\Auditing\Auditable;
+ use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
+ use App\Traits\AuditableCustom;
+ class Test extends Model implements AuditableContract
- class Test extends Model
{
+ use Auditable, AuditableCustom {
+ AuditableCustom::transformAudit insteadof Auditable;
+ }
AuditableCustom
トレイト内のtransformAudit
メソッドを使用し、Auditable
トレイト内の同名のメソッドは無視するように指定しています。
監視結果
監視結果は以下のような形で出力されます。(一部省略しています)
id | user_type | user_id | event | auditable_type | auditable_id | old_values | new_values | url | ip_address | user_agent | tags | created_at | updated_at |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2 | P-AOoO2LsTgbL3338uNs6ewa3gUUdo | created | App\Models\Test | 0 | 省略 | 省略 | 省略 | 省略 | 省略 | 2023-12-27 07:55:30 | 2023-12-27 07:55:30 | ||
3 | P-AOoO2LsTgbL3338uNs6ewa3gUUdo | updated | App\Models\Test | 0 | 省略 | 省略 | 省略 | 省略 | 省略 | 2023-12-27 07:56:03 | 2023-12-27 07:56:03 |
出力する情報のカスタマイズ等行えるので、ぜひとも使ってみて下さい。
Discussion