Я использую этот пост, чтобы получить / установить токен csrf, используя сеансы без изменений в коде
http://www.yiiframework.com/wiki/274/how-to-validate-csrf-token-with-session/
Если пользователь впервые попадает на страницу, а затем выполняет запросы POST, все они терпят неудачу. (все запросы POST отправляют токен CSRF). Но если пользователь обновит страницу, то все POST-запросы после перезагрузки пройдут!
после большой отладки я обнаружил, что токен CSRF, который я получаю при загрузке первой страницы, больше не будет соответствовать значению, сохраненному в сеансе. Когда пользователь перезагружает страницу, токен csrf изменяется на значение сеанса CSRF, и все запросы POST выполняются успешно.
У меня для автозапуска сеанса установлено значение true. Я также попытался использовать куки вместо сеансов, но такая же проблема возникает. Я также попробовал пользовательское состояние.
У меня, возможно, была эта проблема, так как я впервые начал этот 1-летний проект, но никогда не замечал его до сих пор, это происходит, только если он загружает страницу в первый раз.
Все мои контроллеры расширяют ParentController, который расширяет контроллер. У него есть только конструктор и init.
Я пытался выяснить, вызывается ли он дважды, но пока ничего.
public function __construct($id,$module=null)
{
parent::__construct($id,$module);
// do stuff
}
public function init()
{
// do stuff
}
ниже приведен пример запроса POST после загрузки страницы
$.ajax({
type: "POST",
data: {name:xName,id:xID,YII_CSRF_TOKEN:CSRFTokenValue},
url: "/page/logPageView/",
success: function(data){
}
});
Любые идеи о том, где еще я должен искать? возможные причины такого странного поведения?
Я обнаружил, что проблема связана с кэшированием. Недавно я добавил кеширование в облачном хранилище, которое заставило пользователя впервые получить старый токен CSRF из кэшированного содержимого. Вот почему я не смог восстановить его на своем локальном хосте или тестовом сервере, поскольку они не кэшируются.
Я решил эту проблему, добавив вызов ajax, чтобы получить новый токен при загрузке страницы, а затем использовать этот токен для будущих сообщений. и убедитесь, что вызов getFreshToken не кэшируется.
Других решений пока нет …