All Articles

Laravel:ミドルウェアを使ってデータをマスキングする

Laravelでレスポンスに含まれるセンシティブデータ(氏名,住所や電話番号)を部分的に「*」へ変更する方法をミドルウェアを使って実装する。

<?php

namespace App\Http\Middleware;

use Closure;

class MaskingSensitiveData
{
    private $rulesList = [
        "api/user" => [
            "data.name",
        ],
        "api/address" => [
            "data.name",
            "data.address",
        ]
    ];

    public function handle($request, Closure $next)
    {
        $notAllowedIPs = [ 192.168.1.2 ];
        // マスキングする条件を定義する。今回はIPをみてマスキングするか指定する。
        if(in_array($request->ip(), $notAllowedIPs, TRUE)) {
            $response = $next($request);
            // 正常系だけマスキングする。
            if($response->status() == 200) {
                // 特定のURLだけマスキングする。
                if(array_key_exists($request->path(), $this->rulesList)) {
                    // レスポンス予定のデータをマスキングする。
                    $data = $response->getOriginalContent();
                    $data = json_decode(json_encode($data), true);
                    $rules = $this->rulesList[$request->path()];
                    $data = $this->maskData($data, $rules);
                    $response->setData($data);
                }
            }
            return $response;
        } else {
            // マスキングしない場合は何もしない。
            return $next($request);
        }
    }

    private function maskData($data, $rules)
    {
        $maskString = str_repeat('*', 5);
        foreach($rules as $rule) {
            // ヘルパーでdot記法を使ってデータを上書きする。
            data_set($data, $rule, $maskString);
        }
        return $data;
    }
}

マスキング前のレスポンスデータ

{
  "data": [
    {
      "id": 1,
      "name": "teck-memo-1",
    },
    {
      "id": 2,
      "name": "teck-memo-2",
    },
    {
      "id": 3,
      "name": "teck-memo-3",
    },
  ]
}

マスキング後のレスポンスデータ

{
  "data": [
    {
      "id": 1,
      "name": "*****",
    },
    {
      "id": 2,
      "name": "*****",
    },
    {
      "id": 3,
      "name": "*****",
    }
  ]
}