laravelmiddlewarelaravel-middlewarelaravel-11

Laravel 11 Middleware route group api doesnt work


I have a api project with Laravel 11, and i want to make a middleware for admin api.

AdminMiddleware.php (custom middleware)

<?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 (new dir middleware config)

<?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 route)

<?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"]);
    });
});

I've just try using aliases and api method in config. but in api method case, all api route affected by the middleware. I'd try to use Route::group(['middleware' => 'is_admin'] and directly in api route by use the AdminMiddleware, and call in the method with middleware(AdminMiddleware::class). ya it's doesn't work.


Solution

  • Okay, first of all I want to thank @subha for the solution provided and helped find some problems that are happening in my project. I ended up creating a new project and then moving some of the code to the new project... (I really have a skill issue lol)

    1. solving the route problem. Ive found this video on youtube ( https://www.youtube.com/watch?v=st7DtZA85fw ) this is the work code:
        route::group([
                "middleware" => ["auth:sanctum", "is_admin"]
            ], 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"]);
                });
            });
        });
    

    if I use ->middleware("auth:sanctum"); its not work. this dont work too:

    Route::prefix('/admin')->group([
                "middleware" => ["auth:sanctum", "is_admin"]
            ], function(){....
    
    1. solve the api auth problem (after signin. if user access other method, Auth::user() will return null). (this one is a simple problem actually lol) adding Accept: application/json on request header