定義了兩個中間件:
DesensitizeMiddleware
響應(yīng)數(shù)據(jù)注解脫敏中間件ResponseCaseConverter
響應(yīng)數(shù)據(jù)下劃線轉(zhuǎn)駝峰現(xiàn)出現(xiàn)一個問題:當(dāng)我定一個字段id_card
,數(shù)據(jù)脫敏并將字段名變成idCard
,這個時候,就不能脫敏成功,需將ResponseCaseConverter
移除掉,才能正常響應(yīng)脫敏
中間件配置:
<?php
return [
'@' => [
\Landao\WebmanCore\Middleware\DesensitizeMiddleware::class,
\Landao\WebmanCore\Middleware\ResponseCaseConverter::class
]
];
DesensitizeMiddleware
代碼:
<?php
namespace Landao\WebmanCore\Middleware;
use Landao\WebmanCore\Helpers\DesensitizeHelper;
use Landao\WebmanCore\ParseAnnotation\DesensitizeParse;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
/**
* 注解脫敏中間件
*/
class DesensitizeMiddleware implements MiddlewareInterface
{
/**
* 響應(yīng)數(shù)據(jù)的根路徑
* @var string
*/
protected $rootPath = 'data';
public function process(Request $request, callable $handler): Response
{
// 先執(zhí)行后續(xù)中間件和控制器,獲取響應(yīng)
$response = $handler($request);
// 獲取當(dāng)前控制器和方法
$controller = $request->controller;
$action = $request->action;
// 獲取脫敏規(guī)則
$desensitizeRules = DesensitizeParse::getDesensitizeRules($controller, $action);
if (empty($desensitizeRules)) {
return $response;
}
// 嘗試解析響應(yīng)內(nèi)容
$content = $response->rawBody();
$data = json_decode($content, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return $response;
}
// 支持根路徑配置(如API響應(yīng)格式為 {code:200, data:{...}})
$targetData = &$data;
if (!empty($this->rootPath)) {
$rootFields = explode('.', $this->rootPath);
foreach ($rootFields as $field) {
if (!isset($targetData[$field])) {
// 根路徑不存在,記錄日志并返回原始響應(yīng)
return $response;
}
$targetData = &$targetData[$field];
}
}
// 應(yīng)用脫敏規(guī)則
if (is_array($targetData)) {
// 根數(shù)據(jù)是數(shù)組,遍歷每個元素處理
foreach ($targetData as &$item) {
if (is_array($item)) {
$this->processArrayItem($item, $desensitizeRules);
}
}
} else {
// 根數(shù)據(jù)是對象,直接處理
foreach ($desensitizeRules as $rule) {
$this->applyDesensitize($targetData, $rule['field'], $rule['rule']);
}
}
$response->withBody(json_encode($data, JSON_UNESCAPED_UNICODE));
// 更新響應(yīng)內(nèi)容
return $response;
}
}
ResponseCaseConverter
代碼:
<?php
namespace Landao\WebmanCore\Middleware;
use Landao\WebmanCore\Helpers\CamelHelper;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\Middleware;
/**
* 響應(yīng)數(shù)據(jù)下劃線轉(zhuǎn)駝峰
*/
class ResponseCaseConverter extends Middleware
{
public function process(Request $request, callable $handler): Response
{
// 先執(zhí)行后續(xù)中間件獲取響應(yīng)
$response = $handler($request);
// 只處理JSON響應(yīng)
$contentType = $response->getHeader('Content-Type');
if (strpos($contentType, 'application/json') !== false) {
$body = $response->rawBody();
$data = json_decode($body, true);
// 檢查JSON解碼是否成功
if (json_last_error() === JSON_ERROR_NONE && is_array($data)) {
// 使用CamelHelper轉(zhuǎn)換鍵名
$convertedData = CamelHelper::recursiveConvertNameCaseToCamel($data);
// 更新響應(yīng)內(nèi)容
$newBody = json_encode($convertedData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
$response = $response->withBody($newBody);
}
}
return $response;
}
}
是中間件順序配置錯了嗎?或者有沒有更好的不侵入代碼,去處理這兩個業(yè)務(wù)?