Laravel 8 — Случайное получение «Ключ шифрования приложения не указан»

#php #laravel #rest #caching

Вопрос:

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


Правка #5 (обновлено @ 20.10.2021) К сожалению, вопрос остается без ответа. Я действительно озадачен этим, но еще больше тем, что эта ошибка не появлялась в течение последних нескольких дней, и я понятия не имею, что произошло.

Раньше у меня был пользовательский статический «User::hasRole([‘…’]»-метод, который извлекал роли пользователей при каждой проверке ролей. Самым большим изменением, которое я сделал, было кэширование ролей пользователей в сеансе, чтобы не было необходимости извлекать их каждый раз (поскольку десятки запросов rest ссылались на проверку ролей из БД снова и снова как часть фильтров querybuilders).

 $userRoles = Session()->get('userRoles', function() {
    $user = User::with(['userRoles'])->find(Auth::user()->id);
    Session()->put('userRoles', $user->userRoles);
    return $user->userRoles;
});
 

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

Эти случайные ошибки, казалось, никогда не указывали на один конкретный метод, и ничто не указывало в этом направлении. Похоже, что эта ошибка останется некоторой загадкой, но в настоящее время она больше не вызывает проблем. Лучшее, что я могу предположить, это то, что было слишком много параллельных PHP/SQL-потоков, которые каким-то образом приводят к сбою конвейера ядра в случайных состояниях, когда аутентификация каким-то образом не удалась.

Спасибо всем, кто пытался помочь.

Изменение #4 (обновлено @ 14.9.2021) Изменение драйвера кэша из файла в массив не решило проблему. Одна конечная точка только что вернула «не прошедшее проверку подлинности»-сообщение, даже если пользователь аутентифицирован.

Правка № 3, проблема сохраняется, пытаюсь подвести итог:

  • Ключ БЫЛ сгенерирован и даже регенерирован несколько раз
  • Laravel 8, XAMPP
  • Несколько раз запускал config:кэш. Если кэш конфигурации был очищен, проблема возникает чаще, но в настоящее время, возможно, 1/100-200 вызовов REST заканчиваются сбоем более или менее случайным образом. Этого не происходит на производственном сервере LAMP.
  • This problem causes randomly different errors, all somehow related to user session
  • No application encryption key
  • 401 — unauthenticated
  • SQL Connection error (even though either refreshing page / rerunning post works like a charm, and only 1 of ~20 REST-actions on single page load might end up to this state).
  • Doesn’t seem to be CSRF-token related error since sessions are live (as other REST-calls are not failing), but for some reason Axios doesn’t report XSRF-token on RESPONSE-headers whenever this error occurs. Token is present on REQUEST-headers… still looks like backend is unable to find session?
  • Currently using file-based session handling, going to try memory-based

У меня возникла проблема с тем, что Laravel выдает HTTP — код 500- «Ключ шифрования приложения не указан»-случайная ошибка на моих маршрутах rest. Конечно, я установил и даже сбросил ключ с помощью Artisan, так что это не должно быть проблемой.

Эта проблема всегда присутствовала, с тех пор как я начал свой проект на Laravel 6. Довольно быстро я смог отследить проблему в кэше. В основном, когда кэш был стерт с помощью «кэш php artisan:очистить», остальные маршруты начали отказывать, около 5% всех запросов. Когда кэш был сгенерирован снова с помощью «php artisan config:кэш», проблема была решена. По какой-то причине кажется, что .env-переменные не регистрируются или читаются неправильно при очистке кэша? Тем не менее, при разработке не возникало проблем, и кэш был настроен.

Я обновил свой проект с Laravel 6 до 8, и теперь, похоже, эта проблема начала воспроизводиться, и я не могу найти причину.

Мое приложение имеет ~10-20 начальных атомарных обращений к конечным точкам отдыха для предоставления базовой информации для инициализации Vue SPA. Все эти запросы выполняются асинхронно, и время от времени (возможно, один раз на 10 страниц обновляется / повторная инициализация) один из этих вызовов может завершиться ошибкой.

Запускаю все по последней версии XAMPP. Не используйте XDebug или что-либо еще, что может блокировать вызовы. Интересно, сталкивался ли кто-нибудь еще с этой проблемой?

Редактировать:

Кроме того, я могу получить очень случайные ошибки «401 — не прошедшие проверку подлинности». Проблема очень похожа на ошибку ключа приложения. Например, этот снимок был сделан после ~20 минут активности в веб-браузере при переходе с одной страницы на другую. Все остальные звонки до и после также были за аутентификацией, но этот единственный 401 появился из ниоткуда.

введите описание изображения здесь

Изменить 2:

Изменение лотерейного номера не исправило ситуацию.

Комментарии:

1. Проверьте маршруты с ошибками, чтобы узнать, является ли ошибка ошибкой Laravel или ошибкой, возникшей на веб-сервере. Если это ошибка laravel, вы можете установить дополнительные контрольные точки ведения журнала в промежуточном программном обеспечении и маршрутах (или даже временно в коде поставщика, просто чтобы посмотреть, что происходит). Кроме того, вам действительно следует правильно настроить свой сервер, чтобы он не использовался /public для запросов

2. Это обычная ошибка Laravel с чрезвычайно длинным стеком кернера. Я также знаю о общедоступной маршрутизации, но это не проблема на моем сервере разработки, так как у меня другая маскировка на сервере *nix с .htaccess, Это может быть проблема с промежуточным программным обеспечением, но проблема в том, что неудачные маршруты кажутся случайными. Обновление или отзыв маршрута проходит нормально. Такое ощущение, что параллельные вызовы каким-то образом «забудут» или «отменят регистрацию» аутентифицированного пользователя случайным образом

3. все ошибки laravel, как правило, имеют чрезвычайно длинный стек ядра. Вещи, которые необходимо проверить с помощью 401 ошибки (для запросов с сохранением состояния), обычно включают проверку того, был ли отправлен правильный файл cookie сеанса, правильно ли был загружен сеанс.

4. Я верю, что вы, возможно, на что-то напали. Все ОСТАЛЬНЫЕ запросы, которые проходят, имеют «set-cookie» с длинным значением с «Заголовками ответов», такими как «XSRF-ТОКЕН=eyJpd ……..», но всякий раз, когда запрос завершается неудачно, кажется, что отсутствует параметр «set-cookie». Заголовки запросов, похоже, имеют идентичный параметр «Cookie»как для ок, так и для неудачных запросов. У вас есть какие-нибудь указания, почему это может произойти? Я использую Axios на стороне Vue для этих запросов rest.

5. Я действительно думаю, что проблема в вашем сервере xampp. Вы можете попробовать другое приложение, такое как laragon, wamp. Я все время использую laragon, и приложение laravel работает бесперебойно.

Ответ №1:

ПРАВКА: К сожалению, это не было решением. Я подумал, что, может быть, сеансы были смешиванием или чем-то подобным, но нет…

Я верю, что наконец-то нашел ответ.

Для предыдущей версии Laravel (5 и 6), похоже, проблема всегда была с кэшем, так как его очистка решила эту проблему, но переход с 6 -> 8 действительно поднял эту проблему.

У меня была другая проблема, связанная с сеансом, которая, наконец, привела к обнаружению того, что в Laravel 8 что-то изменилось. Мой предыдущий выход из системы был

 public function logout(Request $request) {
    Auth::logout();
    return redirect('/login');
}
 

… но в официальной документации указывалось, что это должно быть:

 public function logout(Request $request) {
    Auth::logout();

    $request->session()->invalidate();
    $request->session()->regenerateToken();

    return redirect('/login');
}
 

Очевидно, сеанс необходимо вручную аннулировать, а также восстановить токен. Я не знаю точной причины, но эти две дополнительные строки, казалось, устранили предыдущие случайные ошибки. Скорее всего, некоторые старые сеансы были активны и запускались в произвольное время на маршрутах REST-API.

Я продолжу отслеживать ситуацию и сообщу, если проблема сохранится, но на данный момент, похоже, проблема решена.

Правка, дополнительные сведения:

Мой ЛогинКонтроллер содержит метод выхода из системы, который, скорее всего, является перезаписью «AuthenticatesUsers.php». Исходный метод выглядит следующим образом:

 public function logout(Request $request) {
    $this->guard()->logout();

    $request->session()->invalidate();

    $request->session()->regenerateToken();

    if ($response = $this->loggedOut($request)) {
        return $response;
    }

    return $request->wantsJson()
        ? new JsonResponse([], 204)
        : redirect('/');
}
 

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

Ответ №2:

Похоже, вы неправильно определили корень своего приложения.. настройте свой веб-сервер так, чтобы корневой

 /path/to/your/laravel/application/public
 

Примечание: /публика в конце

Комментарии:

1. Пожалуйста, прочтите вопрос, прежде чем отвечать. Предложение не предполагает решения заданного вопроса. Общедоступная маршрутизация на сервере разработки в данном случае существует по выбору, а не случайно, и, насколько мне известно, не имеет ничего общего с описанной проблемой.