Reputation: 1874
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
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