49 lines
2.1 KiB
PHP
49 lines
2.1 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Middleware;
|
||
|
||
use Closure;
|
||
use Illuminate\Http\Request;
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
use Illuminate\Support\Facades\Log;
|
||
|
||
/**
|
||
* 🚀 NASA 核心网关:Header 签名安全卫士
|
||
* 🗣️ Verify 发音:/ˈverɪfaɪ/ ( 维瑞发一 ,意为:校验、证实 )
|
||
*/
|
||
final class VerifyNasaToken
|
||
{
|
||
public function handle(Request $oRequest, Closure $fNext): Response
|
||
{
|
||
// 👑 大厂全线对接:丢掉 $oRequest->input(),全面改用 ->header() 降维打击!
|
||
// 🎯 核心微操:Laravel 的 header() 方法天生自带防抖,它对大小写不敏感,
|
||
// 你传 'X-Nasa-Token' 或者 'x-nasa-token',底层都能稳稳咬住!
|
||
$iRequestTime = (int)$oRequest->header('X-Nasa-Timestamp');
|
||
$sClientToken = $oRequest->header('X-Nasa-Token');
|
||
|
||
// 1. 钢铁防御线一:前置空值熔断,连参数都没有的盲流直接当场轰杀
|
||
if (!$iRequestTime || !$sClientToken) {
|
||
return response()->json(['iStatus' => 0, 'sMsg' => 'Security Headers Missing'], 403);
|
||
}
|
||
|
||
// 2. 时效性防御:前后端时间差超过 60 秒判定为重放攻击或过期
|
||
if (abs(time() - $iRequestTime) > 60) {
|
||
Log::warning("🛰️ NASA 网关拦截:请求超时已过期!当前服务器时间: " . time() . ",请求时间: {$iRequestTime}");
|
||
return response()->json(['iStatus' => 0, 'sMsg' => 'Request Expired'], 403);
|
||
}
|
||
|
||
// 3. 验签防御:从配置核心仓掏出密钥,用相同算法重算 Token 对比
|
||
$sLocalSecret = config('nasa.secret');
|
||
$sExpectedToken = md5("timestamp={$iRequestTime}&secret={$sLocalSecret}");
|
||
|
||
// 4. 钢铁防御线二:像素级对撞签名
|
||
if ($sClientToken !== $sExpectedToken) {
|
||
Log::error("🚨 NASA 网关警报:发现非法伪造签名!客户端传值: {$sClientToken},期望值: {$sExpectedToken}");
|
||
return response()->json(['iStatus' => 0, 'sMsg' => 'Invalid Token'], 403);
|
||
}
|
||
|
||
// 5. 安全放行,通电!
|
||
return $fNext($oRequest);
|
||
}
|
||
}
|