Избавьтесь от всех перенаправлений и поведения, не связанного с API, в Laravel 5.8

В настоящее время я сталкиваюсь с некоторыми проблемами при использовании Laravel в качестве серверной части только для API. Я хочу разрабатывать интерфейс отдельно и поэтому рассматриваю Laravel только как API. У меня проблемы при написании тестов. Я все еще использую группу промежуточного программного обеспечения Интернета (не API), а при использовании промежуточного программного обеспечения auth все работает, например, при тестировании с помощью почтальона, но при написании теста.

Пример

public function search_competitions_unauthorized ()
{
    $response = $this->get('/competitions/ABCDEFG');

    $response->assertStatus(401);
}

Конечная точка /competitions/ABCDEFG защищена промежуточным программным обеспечением аутентификации.

Я получаю 500 в качестве кода ответа, потому что не существует маршрута с определенным именем login. Это легко решить (создать маршрут с именем для входа), но я хочу, чтобы Laravel обрабатывал каждый запрос как запрос API, не имеющий перенаправлений.

Я пробовал несколько вещей, чтобы избавиться от этого поведения.

Я определил новый класс DefaultRequest, расширяющий Illuminate\Http\Request

class DefaultRequest extends Request
{
    public function expectsJson()
    {
        return true;
    }

    public function wantsJson()
    {
        return true;
    }
}

Я изменил index.php в общей папке.

$response = $kernel->handle(
    $request = App\Http\Requests\DefaultRequest::capture()
);

Кроме того, все запросы, используемые в моих контроллерах, используют это по умолчанию. Поскольку у меня была такая же проблема с проверкой запроса, я также добавил этот метод в свой запрос по умолчанию.

protected function failedValidation(Validator $validator)
{
    throw new HttpResponseException(response()->json($validator->errors(), 422));
}

У меня такое чувство, что решить эту проблему должно было легче. Похоже, что в целом это было бы проблемой для меня только во время тестирования, и я мог бы установить определенные заголовки в своих тестах. Но я хотел отключить все эти варианты перенаправления, так как НИКОГДА не хочу их для проекта.


person Frnak    schedule 31.03.2019    source источник


Ответы (1)


Я решил это, разместив проверку типа запроса в app/Exceptions/Handler.php, например:

public function render($request, Exception $e)
{
    ...
    // handling unauthenticated requests
    if ($e instanceof \Illuminate\Auth\AuthenticationException) {
        if (
            $request->wantsJson() ||
            $request->expectsJson() ||
            array_get($request->route()->action, 'prefix') == 'api'
        ) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }
        return redirect()->route('login');
    }
    ...
}
person tectiv3    schedule 01.04.2019
comment
Я понимаю, что это правильное решение, но на самом деле я ищу возможность принудительно использовать json-ответ везде, а не только для определенных типов исключений. - person Frnak; 02.04.2019
comment
Ну, кроме исключений, все должно обрабатываться вашими контроллерами ресурсов. Вы можете создать ApiController с помощью метода ответа, например: protected function respond($data, $statusCode = 200, $headers = []) { return response()->json($data, $statusCode, $headers); } И просто наследовать от него в любом другом контроллере. - person tectiv3; 03.04.2019