#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. Пожалуйста, прочтите вопрос, прежде чем отвечать. Предложение не предполагает решения заданного вопроса. Общедоступная маршрутизация на сервере разработки в данном случае существует по выбору, а не случайно, и, насколько мне известно, не имеет ничего общего с описанной проблемой.