webman
webman copied to clipboard
Middleware doesn't stop execution of Controller
Hi Walker, first of all i want to say that i love your framework.
Maybe i do something wrong but it seems like the middleware doesn't stop the execution if you return a response. I am using webman-framework 1.6.7. You can replicate the problem like this:
route.php:
Route::group('/v1', function () {
Route::get('/auth/login', [app\controller\IndexController::class, 'index']);
})->middleware([
app\middleware\AuthMiddleware::class,
app\middleware\RateLimitMiddleware::class
]);
AuthMiddleware.php
namespace app\middleware;
use support\Log;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
class AuthMiddleware implements MiddlewareInterface
{
public function process(Request $request, callable $handler): Response
{
Log::info('AuthMiddleware');
$response = $request->method() == 'OPTIONS' ? response('') : $handler($request);
$response->withHeaders([
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Origin' => $request->header('origin', '*'),
'Access-Control-Allow-Methods' => $request->header('access-control-request-method', '*'),
'Access-Control-Allow-Headers' => $request->header('access-control-request-headers', '*'),
]);
$token = $request->header('Authorization');
if (!$token || !$this->validateToken($token)) {
return json(['error' => 'Unauthorized'])->withStatus(401);
}
return $handler($request);
}
protected function validateToken($token): bool
{
return $token === 'Bearer ' . base64_encode('your-secret-key');
}
}
webman Log:
[2024-12-08 23:54:00] default.INFO: AuthMiddleware [] []
[2024-12-08 23:54:00] default.INFO: RateLimitMiddleware [] []
[2024-12-08 23:54:00] default.INFO: IndexController [] []
Web Response:
{
"error": "Unauthorized"
}
The key is
$response = $request->method() == 'OPTIONS' ? response('') : $handler($request);
$handler($request) has been executed , this will lead to the continued execution of RateLimitMiddleware and IndexController.
So the codes like this will work.
<?php
namespace app\middleware;
use support\Log;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
class AuthMiddleware implements MiddlewareInterface
{
public function process(Request $request, callable $handler) : Response
{
Log::info('AuthMiddleware');
if ($request->method() == 'OPTIONS') {
$response = response('');
} else {
$token = $request->header('Authorization');
if (!$token || !$this->validateToken($token)) {
return json(['error' => 'Unauthorized'])->withStatus(401);
}
$response = $handler($request);
}
return $response->withHeaders([
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Allow-Origin' => $request->header('origin', '*'),
'Access-Control-Allow-Methods' => $request->header('access-control-request-method', '*'),
'Access-Control-Allow-Headers' => $request->header('access-control-request-headers', '*'),
]);
}
protected function validateToken($token): bool
{
return $token === 'Bearer ' . base64_encode('your-secret-key');
}
}