有没有办法在laravel中使用两个身份验证中间件?
Is there a way to use two authentication middlewares in laravel?
我在 Laravel 和基本身份验证中实现了护照身份验证。
我有 UserController,在里面,我有构造方法:
public function __construct()
{
$this->middleware('auth.basic.once')->except(['index', 'show']);
$this->middleware('auth:api')->except(['index', 'show']);
}
OnceBasic 中间件:
public function handle($request, Closure $next)
{
if(Auth::guard('api')->check())
return $next($request);
else
return Auth::onceBasic() ?: $next($request);
}
在 OnceBasic 中间件中,我能够检查用户是否使用 auth:api
进行了身份验证,然后我阻止身份验证尝试使用 onceBasic
,因此在使用访问令牌。但是当尝试使用 onceBasic(email, password) 进行身份验证时它失败了,因为 auth:api
也尝试进行身份验证并且它失败了(尝试调用默认 \App\Http\Middleware\Authenticate.php
中的 redirectTo()
方法)
我的问题是有没有一种方法可以同时使用这两种中间件,只成功验证一个而阻止另一个工作?
我为两个守卫使用同一个控制器的方法需要将两组不同的路由指向控制器。我在这个 中提供了一个示例,这里再次给出示例代码:
<?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');
////////////////////////////////////////////////////////////
});
});
因此,当管理员用户进入 admin/test 时,它使用管理员身份验证守卫,而当普通用户进入 /test 时,它使用标准身份验证守卫。这两个都使用相同的控制器。
然后我为我的应用程序创建了一个基本控制器。以下是我如何确定使用 guard 来访问构造函数中的路由:
<?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);
}
}
我在 Laravel 和基本身份验证中实现了护照身份验证。 我有 UserController,在里面,我有构造方法:
public function __construct()
{
$this->middleware('auth.basic.once')->except(['index', 'show']);
$this->middleware('auth:api')->except(['index', 'show']);
}
OnceBasic 中间件:
public function handle($request, Closure $next)
{
if(Auth::guard('api')->check())
return $next($request);
else
return Auth::onceBasic() ?: $next($request);
}
在 OnceBasic 中间件中,我能够检查用户是否使用 auth:api
进行了身份验证,然后我阻止身份验证尝试使用 onceBasic
,因此在使用访问令牌。但是当尝试使用 onceBasic(email, password) 进行身份验证时它失败了,因为 auth:api
也尝试进行身份验证并且它失败了(尝试调用默认 \App\Http\Middleware\Authenticate.php
中的 redirectTo()
方法)
我的问题是有没有一种方法可以同时使用这两种中间件,只成功验证一个而阻止另一个工作?
我为两个守卫使用同一个控制器的方法需要将两组不同的路由指向控制器。我在这个
<?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');
////////////////////////////////////////////////////////////
});
});
因此,当管理员用户进入 admin/test 时,它使用管理员身份验证守卫,而当普通用户进入 /test 时,它使用标准身份验证守卫。这两个都使用相同的控制器。
然后我为我的应用程序创建了一个基本控制器。以下是我如何确定使用 guard 来访问构造函数中的路由:
<?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);
}
}