我有一个 Laravel 11 的 api 项目,我想为管理 api 制作一个中间件。
AdminMiddleware.php(自定义中间件)
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$user = Auth::user();
if (!$user) {
return response()->json([
'status' => 'forbidden',
'message' => 'You need to log in first.'
], 403);
}
if ($user->authority !== 'admin') {
return response()->json([
'status' => 'forbidden',
'message' => 'You are not an administrator.'
], 403);
}
return $next($request);
}
}
bootstrap/app.php(新的 dir 中间件配置)
<?php
use App\Http\Middleware\AdminMiddleware;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
"is_admin" => AdminMiddleware::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
api.php(api 路由)
<?php
use App\Http\Controllers\ProductController;
use App\Http\Controllers\UserController;
use App\Http\Middleware\AdminMiddleware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Route::prefix('/v1')->group(function () {
Route::prefix('/admin')->group(function () {
Route::prefix('/product')->group(function () {
Route::get('/', [ProductController::class, "index"]);
Route::post('/', [ProductController::class, "store"]);
Route::get('/{id}', [ProductController::class, "show"]);
Route::put('/{id}', [ProductController::class, "update"]);
Route::delete('/{id}', [ProductController::class, "destroy"]);
});
Route::prefix('/user')->group(function () {
Route::get('/', [UserController::class, "index"]);
Route::get('/{id}', [UserController::class, "show"]);
Route::post('/{id}', [UserController::class, "store"]);
Route::put('/{id}', [UserController::class, "update"]);
Route::delete('/{id}', [UserController::class, "destroy"]);
});
})->middleware("is_admin");
Route::prefix('/auth')->group(function () {
Route::post('/signup', [UserController::class, "signup"]);
Route::post('/signin', [UserController::class, "signin"]);
Route::post('/signout', [UserController::class, "signout"]);
});
Route::prefix('/product')->group(function () {
Route::post('/', [ProductController::class, "product"]);
});
});
我刚刚尝试在配置中使用别名和 api 方法。但在 api 方法的情况下,所有 api 路由都受中间件影响。我尝试使用 Route::group(['middleware' => 'is_admin'] 并直接在 api 路由中使用 AdminMiddleware,并使用 middleware(AdminMiddleware::class) 调用该方法。是的,它不是工作。
如果您希望只有
admin
权限才能通过AdminMiddleware
访问这些路由,那么您需要对那些具有null
权限的用户再次进行检查。
因为在 PHP 中
null
是一种没有值的数据类型。
如果您的
AdminMiddleware
正确分配给 routes
那么下面的代码将起作用。
尝试一下
AdminMiddleware
。
public function handle(Request $request, Closure $next): Response
{
$user = Auth::user();
if (!$user) {
return response()->json([
'status' => 'forbidden',
'message' => 'You need to log in first.'
], 403);
}
if ((is_null($user->authority) || $user->authority !== 'admin')) {
return response()->json([
'status' => 'forbidden',
'message' => 'You are not an administrator.'
], 403);
}
return $next($request);
}
使用上面的代码就可以了。