Ali Ali
Ali Ali

Reputation: 1874

Is there a way to use two authentication middlewares in laravel?

I implemented passport authentication in Laravel and the basic auth. I have UserController and inside it, I have the constructor methode:

 public function __construct()
    {
        $this->middleware('auth.basic.once')->except(['index', 'show']);   
        $this->middleware('auth:api')->except(['index', 'show']); 
    }

The OnceBasic middleware:

public function handle($request, Closure $next)
    {
        if(Auth::guard('api')->check())
        return $next($request);
        else
        return Auth::onceBasic() ?: $next($request);
    }

In the OnceBasic middleware, I'm able to check if the user authenticated using the auth:api then I prevent the authentication from trying to use the onceBasic, So it worked correctly when using the access token. But it fails when trying to authenticate using the onceBasic(email, password) because the auth:api trying to authenticate too and it fails(trying to call the redirectTo() methods inside the default \App\Http\Middleware\Authenticate.php )

My question is there a way to use both of these middlewares, to only successfully authenticate one and prevent the other from working?

Upvotes: 0

Views: 1467

Answers (1)

mchljams
mchljams

Reputation: 441

My approach to using the same controller for two guards required pointing two separate groups of routes to the controllers. I provided an example in this answer to a similar question, here is the example code again:

<?php

    Route::middleware(['auth:admin_api'])->group(function () {
        Route::prefix('admin')->group(function () {
            Route::name('api.admin.')->group(function () {

                ////////////////////////////////////////////////////////////
                /// PLACE ADMIN API ROUTES HERE ////////////////////////////
                ////////////////////////////////////////////////////////////
                Route::apiResource('test','App\Http\Controllers\API\MyController');
                ////////////////////////////////////////////////////////////
            });
        });
    });

    Route::middleware(['auth:api'])->group(function () {
        Route::name('api.')->group(function () {
            ////////////////////////////////////////////////////////////
            /// PLACE PUBLIC API ROUTES HERE ///////////////////////////
            ////////////////////////////////////////////////////////////
            Route::apiResource('test', 'App\Http\Controllers\API\MyController');
            ////////////////////////////////////////////////////////////
        });
    });

So when an admin user goes to admin/test, it uses the admin auth guard, and when a normal user goes to /test it uses the standard auth guard. Both of these use the same controller.

I then created a base controller for my app. Here is how I determined with guard is being used to access the route in the constructor:

<?php


use Illuminate\Http\Response;
use App\Http\Controllers\Controller;

class BaseController extends Controller
{
    protected $user;

    protected $isAdmin = false;

    public function __construct()
    {
        if(Auth::guard('admin_api')->check()) {
            $this->user = Auth::guard('admin_api')->user();
            $this->isAdmin = true;
        } elseif(Auth::guard('api')->check()) {
            $this->user = Auth::guard('api')->user();
            $this->isAdmin = false;
        } else {
            return response()->json([
                'message' => 'Not Authorized',
            ], 401);
        }
    }

Upvotes: 1

Related Questions