2015-04-01 2 views
0

Мой токен CSRF, похоже, отключен. Есть ли способ предотвратить это?CSRF токен в Yii тайм-аут?

У меня есть приложение с одной страницей, где мой интерфейс написан в AngularJS. По большей части мой токен CSRF проверяется, и я могу подтвердить, что я посылаю токен через каждый запрос. Однако иногда я вижу ошибки с моего сервера, говорящие, что «токен CSRF не может быть проверен». Я не полностью понимаю внутренности того, как проверяется токен CSRF, но есть ли причина, почему это произойдет?

Наша заявка также является международной, но из-за нашей серверной инфраструктуры происходит замедление в определенных географических районах. Я заметил (только ad-hoc), что, если, например, пользователь загружает файл, и запрос занимает больше времени, чем обычно, вероятность того, что токен CSRF окажется недопустимым, выше.

Хотелось бы услышать какие-либо идеи об этом! Заранее спасибо!

+0

Вы генерируете токен CSRF для каждого запроса? – TNC

ответ

0

Я думаю, что Yii оценивает CSRF против файла cookie, попробуйте расширить базовый класс CHttpRequest и утвердить его на сеанс. Это приводит к переменному времени сеанса работы с действительностью CSRF.

class HttpRequest extends CHttpRequest 
{ 
    public function getCsrfToken() 
     { 
      if ($this->_csrfToken === null) { 
       $session = Yii::app()->session; 
       $csrfToken = $session->itemAt($this->csrfTokenName); 
       if ($csrfToken === null) { 
        $csrfToken = sha1(uniqid(mt_rand(), true)); 
        $session->add($this->csrfTokenName, $csrfToken); 
       } 
       $this->_csrfToken = $csrfToken; 
      } 

      return $this->_csrfToken; 
     } 

     public function validateCsrfToken($event) 
     { 
      if ($this->getIsPostRequest()) { 
       // only validate POST requests 
       $session = Yii::app()->session; 

       $headers = Common::getAllHeaders(); 

       if ($session->contains($this->csrfTokenName) && (isset($_POST[$this->csrfTokenName]) || isset($headers['X-Csrf-Token']))) { 
        $tokenFromSession = $session->itemAt($this->csrfTokenName); 
        $tokenFromPost = isset($_POST[$this->csrfTokenName]) ? $_POST[$this->csrfTokenName] : $headers['X-Csrf-Token']; 
        $valid = $tokenFromSession === $tokenFromPost; 
       } else { 
        $valid = false; 
       } 
       if (!$valid) { 
        header("Location: " . Yii::app()->createAbsoluteUrl(Yii::app()->request->url)); 
       } 
      } 
     } 
} 

И использовать его как в файле конфигурации:

'request' => array(
      'enableCsrfValidation' => true, 
      'class' => 'HttpRequest', 

      'csrfCookie' => array(
       'httpOnly' => true, 
       'secure' => true 
      ), 

Примечание: Donot скопировать и вставить все содержимое. Измените в соответствии с вашими потребностями. Это только начало. Надеюсь, я понимаю вашу проблему.

Смежные вопросы