7

誰かがSymfony1.4のフォームのCSRFトークンエラーメッセージをどこで/どのようにカスタマイズするか教えてもらえますか?ログインにsfDoctrineGuardを使用しています。特にこのフォームでは、セッションが終了してもページを開いたままにすると、「CSRF攻撃が検出されました」という非常にユーザーフレンドリーなエラーがスローされます。「このセッションは期限切れです。ホームページに戻ってもう一度やり直してください」のように聞こえます。

フォームクラスでこれを行う正しい方法は何ですか?

ありがとう。

4

6 に答える 6

5

唯一の方法は上書きすることのようsfForm::addCSRFProtection()です。

/lib/form/BaseForm.class.php次のコードを追加できます。

class BaseForm extends sfFormSymfony
{
    public function addCSRFProtection($secret = null)
    {
        parent::addCSRFProtection($secret);
        if (array_key_exists(self::$CSRFFieldName, $this->getValidatorSchema())) {
            $this->getValidator(self::$CSRFFieldName)->setMessage('csrf_attack', 'This session has expired. Please return to the home page and try again.');
        }
    }
}

親メソッドを呼び出した後、CSRFフィールドに関連付けられたバリデーターを取得し、コードのメッセージを変更しますcsrf_attack

編集:バリデーターが存在するかどうかも確認する必要があります。一部のフォームでは、CSRF保護が無効になっている可能性があります。

お役に立てれば!

于 2010-04-06T11:35:11.957 に答える
3

これらの回答はいずれも、ハッキングではない方法でエラーメッセージのプレフィックスとなる「CSRFtoken:」ラベルを削除する方法を説明していません(たとえば、トークン名を変更することは悪い考えです!)。

ラベルを削除する唯一の適切な方法は、CSRFバリデーターを拡張してグローバルエラーをスローすることです。これを行っている間、エラーメッセージを変更することもできます。

class myValidatorCSRFToken extends sfValidatorCSRFToken
{
  protected function configure($options = array(), $messages = array())
  {
    parent::configure($options, $messages);
    $this->addMessage('csrf_attack', 'Your session has expired. Please return to the home page and try again.');
  }

  protected function doClean($value)
  {
    try {
      return parent::doClean($value);
    } catch (sfValidatorError $e) {
      throw new sfValidatorErrorSchema($this, array($e));
    }
  }
}

次に、 :をオーバーライドsfForm::addCSRFProtectionして、このバリデーターを使用するようにフォームを設定しましょう。BaseForm

public function addCSRFProtection($secret = null)
{
  parent::addCSRFProtection($secret);
  if (isset($this->validatorSchema[self::$CSRFFieldName])) //addCSRFProtection doesn't always add a validator
  {
    $this->validatorSchema[self::$CSRFFieldName] = new myValidatorCSRFToken(array(
        'token' => $this->validatorSchema[self::$CSRFFieldName]->getOption('token')
    ));
  }
}
于 2011-04-22T18:39:50.590 に答える
2

1.4.4では、naagのコードを次のように変更する必要がありました...

public function addCSRFProtection($secret = null)
{
  parent::addCSRFProtection($secret);
  if (isset($this->validatorSchema[self::$CSRFFieldName])) {
    $this->validatorSchema[self::$CSRFFieldName]->setMessage('csrf_attack', 'This session has expired. Please refresh and try again.');
  }
}

これで動作しましたが、「csrfトークン:」ビットはまだエラーメッセージに表示されます。

于 2010-05-21T11:12:26.240 に答える
2

以前の回答を改善するために、私が使用するコードは次のとおりです。

public function addCSRFProtection($secret = null)
  {
    parent::addCSRFProtection($secret);
    if (isset($this->validatorSchema[self::$CSRFFieldName])) {
      $this->validatorSchema[self::$CSRFFieldName]->setMessage('csrf_attack', 'This session has expired. Please refresh and try again.');
      $this->getWidgetSchema()->getFormFormatter()->setNamedErrorRowFormatInARow("    <li>%error%</li>\n");
    }
  }

NamedErrorRowFormatInARowのデフォルト値は"<li>%name%: %error%</li>\n"、名前とコロンを追加することです。すべてのフォームとすべてのグローバルエラーの値が変更されるため、注意してください。

カスタムフォームフォーマッターを作成し、必要なフォームで使用して、フィールドを変更することもできます。詳細については、こちらのドキュメントをご覧ください。

于 2012-09-28T19:58:48.627 に答える
1

イベントディスパッチャを使用します。これをチェックしてくださいhttp://bluehorn.co.nz/2010/07/15/how-to-change-csrf-attack-message-in-symfony-1-2/

私はSymfony1.2用に作成しましたが、イベントディスパッチャーを使用しているため、Symfony1.4でも機能する可能性があります。

于 2010-07-14T23:53:42.203 に答える
1

もちろん、CSRFトークンフィールドのラベルをグローバルに設定することで、「csrftoken:」プレフィックスを削除またはカスタマイズできると思います。

于 2011-01-19T15:11:28.443 に答える