#laravel
#laravel
Вопрос:
Как получить промежуточное программное обеспечение для текущего маршрута?
Я пытаюсь настроить обработчик исключений на работу по-разному в зависимости от того, находитесь ли вы в определенной части веб-сайта, проверяя, добавлено ли промежуточное программное обеспечение в маршрут.
<?php
namespace AppExceptions;
//use IlluminateFoundationExceptionsHandler as ExceptionHandler;
use AbrighamLaravelEmailExceptionsExceptionsEmailHandler as ExceptionHandler;
use IlluminateRoutingExceptionsInvalidSignatureException;
use IlluminateSupportFacadesRoute;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param Throwable $exception
* @return void
*
* @throws Exception
*/
public function report(Throwable $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param IlluminateHttpRequest $request
* @param Throwable $exception
* @return SymfonyComponentHttpFoundationResponse
*
* @throws Throwable
*/
public function render($request, Throwable $exception)
{
switch(true) {
case $exception instanceof IlluminateSessionTokenMismatchException:
// Redirect back if form invalid
return redirect()
->back()
->withInput($request->except($this->dontFlash))
->withErrors('The form has expired due to inactivity. Please try again');
break;
case $exception instanceof IlluminateDatabaseEloquentModelNotFoundException:
// Redirect back with message if model not found error
$redirect = app('redirect');
// Check for different url to prevent redirect loop
if (request()->fullUrl() === $redirect->back()->getTargetUrl()){
// $currentRouteMiddleware = request()->route()->controllerMiddleware() returns empty array
// $currentRouteMiddleware = Route::current()->router->getMiddleware(); router is private
$response = $redirect->to(isset($currentRouteMiddleware['admin.user']) ? '/admin' : '/');
} else {
$response = $redirect->back();
}
return $response
->withInput($request->except($this->dontFlash))
->withErrors('That page could not be found. Please try again or report the broken link: ' . $request->getRequestUri());
break;
}
return parent::render($request, $exception);
}
}
Если я дамп текущего маршрута внутри маршрутизатора, он показывает массив промежуточного программного обеспечения, который мне нужно проверить: dd(Route::current())
но, похоже, нет способа доступа к текущему маршрутизатору, например: $currentRouteMiddleware = Route::current()->router->getMiddleware();
Ответ №1:
Есть несколько вариантов, основанных на том, что вы ищете.
Если вы хотите, чтобы все псевдонимы промежуточного программного обеспечения были назначены маршруту, вы можете использовать:
Route::current()->gatherMiddleware();
Это не расширяет назначенные группы промежуточного программного обеспечения, поэтому результат этого может выглядеть примерно так:
[
'web',
'admin.user'
]
Если вы хотите, чтобы все классы промежуточного программного обеспечения были назначены маршруту, вы можете использовать:
Route::gatherRouteMiddleware(Route::current());
Это даст вам классы, но не будет иметь связанных псевдонимов или групп для классов. Результат от этого может выглядеть следующим образом:
[
"AppHttpMiddlewareEncryptCookies",
"IlluminateCookieMiddlewareAddQueuedCookiesToResponse",
"IlluminateSessionMiddlewareStartSession",
"IlluminateViewMiddlewareShareErrorsFromSession",
"AppHttpMiddlewareVerifyCsrfToken",
"IlluminateRoutingMiddlewareSubstituteBindings",
"TCGVoyagerHttpMiddlewareVoyagerAdminMiddleware"
]
Ответ №2:
Route::getMiddleware()
В обработчике это просто список AppHttpKernel::$routeMiddleware
.
dd(Route::getMiddleware());
array:7 [▼
"auth" => "AppHttpMiddlewareAuthenticate"
"auth.basic" => "IlluminateAuthMiddlewareAuthenticateWithBasicAuth"
"guest" => "AppHttpMiddlewareRedirectIfAuthenticated"
"admin" => "AppHttpMiddlewareAdminMiddleware"
// ...
]
Рекомендуется объявить константу (или глобальную переменную) и проверить, объявлена ли соответствующая константа в обработчике, чтобы проверить, прошла ли AdminMiddleware
передача.
// app/Http/Middleware/AdminMiddleware.php
public function handle($request, Closure $next)
{
// if ... return ...
define('__APP_IS_ADMIN', true);
return $next($request);
}
// app/Exceptions/Handler.php
public function render($request, Exception $e)
{
// ...
$response = $redirect->to(defined('__APP_IS_ADMIN') ? '/admin' : '/');
Ответ №3:
request()->route()->controllerMiddleware();
Комментарии:
1. К сожалению, это всегда возвращает пустой массив. Я делаю это внутри обработчика исключений, но даже внутри контроллера он ничего не возвращает.
Ответ №4:
Перечислите промежуточные ПРОГРАММЫ, применяемые в текущем маршруте внутри App Exceptions Handler. Использование в неаутентифицированном методе.
/**
* Convert an authentication exception into a response.
*
* @param IlluminateHttpRequest $request
* @param IlluminateAuthAuthenticationException $exception
* @return SymfonyComponentHttpFoundationResponse
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
return $request->expectsJson()
? response()->json(['message' => $exception->getMessage()], 401)
: redirect()->guest(in_array('admin', $request->route()->middleware(), true) ? route('admin.login') : route('login'));
}
Я использовал это, чтобы получить промежуточное программное обеспечение «admin» и перенаправить пользователя на правильную страницу входа.