Почему Laravel `FormRequest » сначала авторизует и проверяет ввод в последнюю очередь? Как мне изменить это поведение? Какие неожиданные недостатки могут возникнуть?

#laravel #validation #authorization #laravel-validation #laravel-formrequest

Вопрос:

Я использую пользовательские классы запросов, которые расширяют Laravavel FormRequest (Руководство пользователя, документация API), чтобы

  1. для проверки входных параметров и
  2. для авторизации запроса.

Скелет выглядит так:

 class MyRequest extends FormRequest {
  /**
   * Determines if the user is authorized to make this request.
   */
  public function authorize(): bool {
    // TODO: Put your authorization logic here
  }

  /**
   * Returns the validation rules that apply to the request.
   */
  public function rules(): array
  {
    // TODO: Define your validation rules here
  }
}
 

Обычно и конкретно в моем случае решение о том, имеет ли пользователь право делать запрос, зависит от входных параметров. Следовательно, я ожидал, что синтаксис входных параметров сначала проверяется, а затем запрос авторизуется. В частности, для правильной авторизации очень часто необходимо запускать запросы к БД, используя входные параметры запроса. Очевидно, что запрос к БД следует выполнять только в том случае, если синтаксис входных параметров уже проверен.

Сказав это, я ожидал бы следующего порядка событий

  1. аутентификация пользователя (происходит в промежуточном программном обеспечении, здесь выходит за рамки)
  2. проверка входных параметров (например, вызывается метод rules )
  3. авторизация пользователя (например, вызывается метод authorize )

Однако Laravel вызывает 2. и 3. в обратном порядке. Следовательно, пользователь должен быть авторизован в тот момент, когда ввод еще не был подтвержден. Похоже, что проблемный код находится внутри IlluminateValidationValidatesWhenResolvedTrait::validateResolved . Этот метод сначала вызывает логику авторизации, а затем требует проверки входных данных.

Предложенное решение

На данный момент я подумываю о том, чтобы написать свой собственный базовый класс FormRequestWithBugfix , расширить его от FormRequest перезаписи validateResolved таким образом, чтобы он вызывал методы, которые он лучше упорядочивает, а затем использовал FormRequestWithBugfix в качестве общего базового класса во всем моем проекте.

Questions:

  1. Будет ли предлагаемое решение работать? Есть ли какие-либо угловые случаи, о которых я должен знать, которые не рассматриваются предлагаемым решением?
  2. Каковы причины, по которым Laravel реализовал это таким образом на первом этапе? Я предполагаю, что должны быть веские причины сделать это так, как это сделал Ларавель.
  3. Есть ли какие-либо последствия для безопасности, о которых я должен знать? Каковы потенциальные недостатки в случае изменения заказа?