Вопрос или проблема
Я столкнулся с проблемой, когда нонсы становятся недействительными, и невозможно обновить их на новые. В моем примере у меня есть кнопка Facebook Connect и кнопка Facebook Disconnect, каждая со своим нонсом.
Как только нажата любая из этих кнопок, выполняется AJAX-вызов, и другая кнопка отправляется через AJAX и отображается на странице взамен.
Для примера начнем с кнопки Facebook Connect.
<button type="button" id="facebook-connect-button" class="facebook-button" data-nonce="<?php echo wp_create_nonce('ns-social-facebook-authentication'); ?>">
<?php _e('Connect to', NS_USER_SYSTEM_TEXTDOMAIN); ?> Facebook
</button>
После нажатия этой кнопки выполняется AJAX-вызов, который проверяет свойство data-nonce следующим образом:
check_ajax_referer( 'ns-social-facebook-authentication', '_nonce' );
Здесь все работает без проблем, моя привязанная функция работает идеально.
После выполнения этой функции возвращается кнопка Facebook Disconnect, которая выглядит следующим образом, и заменяет оригинальную кнопку.
<button type="button" id="facebook-disconnect-button" class="facebook-disconnect-button" data-nonce="<?php echo wp_create_nonce('ns-social-facebook-disconnect'); ?>">
<?php _e('Disconnect from Facebook', NS_USER_SYSTEM_TEXTDOMAIN); ?>
</button>
После нажатия этой кнопки все работает как и прежде, и на этот раз кнопка Facebook Connect вызывается снова через AJAX. И вот здесь начинается проблема.
Эта новая возвращенная кнопка содержит тот же нонс, который теперь недействителен и возвращает ошибку 403, поскольку он уже был использован ранее.
Похоже, что возврат кнопки через AJAX не обновляет нонс, даже если он уже был использован.
Я также пытался отображать обе кнопки на странице и возвращать только новый нонс через AJAX каждый раз, когда нажимается кнопка, но все равно продолжает возвращать тот же нонс для каждой из кнопок соответственно.
Почему это происходит и как я могу решить эту проблему?
Вы можете просто принудительно обновить страницу после того, как пользователь повторно переключает кнопку подключения.
Конечно, это уже не самый приятный UX, и, вероятно, это не вписывается в ваш план.
Я обнаружил источник моей проблемы. В логике моей функции я вызывал другую функцию, в которой я повторно авторизовывал пользователя. Это приводило к тому, что нонсы, зависящие от пользователя, становились недействительными.
После удаления этой логики все работает как ожидалось!
.
Ответ или решение
Вы столкнулись с проблемой того, что nonces (одноразовые токены безопасности) становятся недействительными после их использования, и их обновление через AJAX-посылки не происходит, что приводит к ошибке 403. В вашем случае у вас есть две кнопки: "Подключиться к Facebook" и "Отключиться от Facebook", каждая из которых использует свой nonce. Проблема заключается в следующем:
После того, как кнопка подключить Facebook нажата, вызывается AJAX-запрос, который проверяет nonce, и все проходит успешно. Возвращается и отображается на странице кнопка для отключения от Facebook с новым nonce. На этом этапе все работает правильно. Однако при нажатии на кнопку "Отключиться от Facebook", AJAX возвращает обратно кнопку "Подключиться", но с тем же nonce, который уже стал недействительным. Это приводит к появлению ошибки 403.
Таким образом, проблема заключается в том, что после AJAX-запроса nonce не обновляется, несмотря на то, что он уже был использован.
Решения проблемы:
-
Обновление Nonces через AJAX: Убедитесь, что при генерации нового содержимого на сервере вы также создаете новый nonce. Одной из ошибок могло быть использование старого nonce из кэшированной сессии. Проверьте кэширование данных и убедитесь, что новый nonce всегда генерируется непосредственно перед отправкой через AJAX. Используйте
wp_create_nonce()
для каждой новой операции. -
Разделение логики проверок и операций: Убедитесь, что логика AJAX и проверка nonces не включают операции, такие как повторный вход пользователя, которые могут повлиять на валидность nonce. В вашем решении проблема заключалась в повторной авторизации, которая обнуляла токены.
-
Тестирование среды выполнения: Проверьте рабочую среду для наличия конфликтов с плагинами или темами, которые могут управлять сессиями или nonce. Используйте отладочные инструменты WordPress для обнаружения и устранения подобных проблем.
-
Идиоматичный подход к UX: Хотя перезагрузка страницы является быстрым исправлением, оно может ухудшить пользовательский опыт. Рассмотрите возможность регистрации новых nonce и обновления их на стороне клиента без перезагрузки всей страницы.
Заключение
Используйте принципы безопасного кодирования с nonce в AJAX, чтобы защищать ваши приложения от CSRF-атак. Невалидность nonce не должна приводить к серьезным сбоям, таким как ошибка 403, если реализованы правильные методы их обновления. Следуя этим рекомендациям, вы сможете обеспечить надежность и удобство использования вашего приложения, улучшив при этом безопасность.
Если у вас остались вопросы или вы хотите внедрить более эффективные решения, рассмотрите возможность привлечения опытных разработчиков или специалистов по безопасности для проведения аудита кода.