2010-04-05 8 views
7

Symfony 1.4의 양식에 대한 CSRF 토큰 오류 메시지를 사용자 정의하는 방법/방법을 알려줄 수 있습니까? 저는 sfDoctrineGuard를 로그인 용으로 사용하고 있습니다. 특히이 양식에서는 세션이 만료 되어도 여전히 페이지가 열려있을 때 "CSRF 공격이 감지되었습니다"라는 매우 사용자에게 친숙하지 않은 오류가 발생합니다. "이 세션이 만료되었습니다. 홈페이지로 돌아가서 다시 시도하십시오."와 같은 소리가 더 좋습니다.Symfony 1.4 : 양식의 CSRF에 대한 사용자 정의 오류 메시지

양식 클래스에서이 작업을 수행하는 올바른 방법은 무엇입니까?

감사합니다.

답변

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 보호가 사용 중지되었을 수 있습니다!

희망이 도움이됩니다. 내가 지금처럼 naag의 코드를 수정 한 1.4.4에서

+0

@naag : 대단히 감사합니다. 몇 가지 시도했지만 그게 아니라, 놀이를해야합니다. 심포니 녀석들의 사소한 감독처럼 보입니다. – Tom

+0

CSRF 유효성 검사기의 존재를 확인하기 위해 내 대답을 편집했습니다 :-) – naag

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.'); 
    } 
} 

이이 작업을 얻었다는 'CSRF 토큰은'비트는 여전히 비록 오류 메시지가 나타납니다.

1

전 세계적으로 CSRF 토큰 필드의 레이블을 설정하여 "csrf token :"접두사를 제거하거나 사용자 정의 할 수 있습니다.

3

이 답변 중 오류 메시지 앞에 접두사가 붙지 않는 방식으로 토큰 이름을 변경하는 등의 "CSRF token :"레이블을 제거하는 방법에 대한 설명은 없습니다.

레이블을 제거하는 유일한 방법은 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)); 
    } 
    } 
} 

,의는 BaseFormsfForm::addCSRFProtection를 재정 의하여이 유효성 검사기를 사용하는 우리의 양식을 설정할 수 있습니다 :

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') 
    )); 
    } 
} 
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"이며 이름과 콜론이 추가됩니다. 모든 양식 및 모든 전역 오류의 값이 변경되므로주의하십시오.

사용자 지정 양식 서식 파일을 만들고 원하는 양식에서 사용하여 필드를 변경할 수도 있습니다.이것에 대한 더 많은 정보는 the documentation here에서 찾아 볼 수 있습니다.

관련 문제