Laravel получает промежуточное программное обеспечение для текущего маршрута

#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» и перенаправить пользователя на правильную страницу входа.