中间件(洋葱模型)
签名:function (Request $request, callable $next): Response。调用 $next($request) 向内传递;返回 Response 即短路。
namespace App\Middleware;
use Mtphp\Http\Request;
use Mtphp\Http\Response;
class Auth
{
public function handle(Request $request, callable $next): Response
{
if (empty($request->header('x-token'))) {
return response()->status(401)->json(['msg' => '未授权']);
}
$resp = $next($request); // 交给内层
return $resp->header('X-Powered', 'mtphp'); // 后置加工
}
}
注册:
- 全局:
config/app.php的middleware数组; - 路由级:
Route::group(['middleware' => [App\Middleware\Auth::class]], ...)或单条Route::get(uri, action, [Auth::class]); - 字符串形式支持
"Class@method"与"ClassName"(默认方法handle)。
14.1 框架内置安全中间件(默认自动开启)
框架在 App::bootstrap() 末尾、应用全局中间件之前自动注册两个内置安全中间件(处于洋葱最外层,能包裹包括 CSRF 在内的全部响应)。它们默认开启,可在 config/app.php 的 security 段关闭或放行:
- 安全响应头(
Mtphp\Http\Middleware\SecurityHeaders):统一补X-Content-Type-Options/X-Frame-Options/Referrer-Policy/Content-Security-Policy/Permissions-Policy;HTTPS 下额外追加Strict-Transport-Security。可在security.headers_list覆盖/新增单项,或把某项设为null关闭(例如暂时关闭 CSP)。 - CSRF 防护(
Mtphp\Http\Middleware\Csrf):采用“无状态双提交 Cookie”方案(无需 Session),对所有非安全方法(POST/PUT/DELETE/PATCH)校验令牌;GET 等安全方法会自动下发 HttpOnly + SameSite=Lax 的令牌 Cookie。开放接口可在security.csrf_except填入路径前缀(如/api)跳过校验。
表单里放入 CSRF 令牌(全局助手,引导时自动加载):
csrf_token(); // 取当前请求令牌字符串
csrf_field(); // 输出 <input type="hidden" name="_token" value="...">
csrf_meta(); // 输出 <meta name="csrf-token" ...>,前端 AJAX 读取后放入 X-CSRF-TOKEN 头
<form method="POST" action="/article">
<?= csrf_field() ?>
<input name="title" ...>
</form>
原则:安全“默认开启、可一行关闭”,既不给开发者添负担,又让新项目开箱即带基础防护。上线前仍建议把
config/app.php的debug改为false。