젠드 프레임워크 폼 해시(토큰)를 AJAX와 함께 사용하는 방법
양식 다중 확인란 양식에 Zend_Form_Element_Hash를 포함했습니다.확인란을 클릭할 때 AJAX 요청을 실행하도록 jQuery를 설정했습니다. 이 AJAX 요청으로 토큰을 전달합니다.첫 번째 AJAX 요청은 잘 작동하지만 이후 요청은 실패합니다.
토큰의 유효성이 확인되면 세션에서 제거될 수 있습니다(홉 = 1.
이러한 요청 중 일부를 완료하기 위해 AJAX를 사용하는 젠드 프레임워크 해시로 양식을 보호하기 위한 공격 계획은 무엇입니까?
저는 결국 Zend_Form_Element_Hash 사용을 포기하고 수동으로 토큰을 생성하여 Zend_Session에 등록한 후 제출 시 확인하였습니다.
서식.
$myNamespace = new Zend_Session_Namespace('authtoken');
$myNamespace->setExpirationSeconds(900);
$myNamespace->authtoken = $hash = md5(uniqid(rand(),1));
$auth = new Zend_Form_Element_Hidden('authtoken');
$auth->setValue($hash)
->setRequired('true')
->removeDecorator('HtmlTag')
->removeDecorator('Label');
컨트롤러.vmdk
$mysession = new Zend_Session_Namespace('authtoken');
$hash = $mysession->authtoken;
if($hash == $data['authtoken']){
print "success";
} else {
print "you fail";
}
이것은 효과가 있는 것처럼 보이며 여전히 사물을 비교적 제정신이고 안전하게 유지합니다.저는 여전히 해시 요소를 사용하고 싶지만, AJAX와 함께 작동할 수 없을 것 같습니다.
모두 감사합니다.
이것이 Ajax 형식의 해시 필드를 처리하는 방법입니다.
class AuthController extends Zend_Controller_Action
{
public function init()
{
$contextSwitch = $this->_helper->getHelper('contextSwitch');
$contextSwitch->addActionContext('index', 'json')
->initContext();
}
public function loginAction()
{
$form = new Application_Form_Login();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
// some code ..
} else {
// some code ..
// Regenerate the hash and assign to the view
$reservationForm->hash->initCsrfToken();
$this->view->hash = $reservationForm->hash->getValue();
}
}
$this->view->form = $form;
}
}
그런 다음 보기 스크립트에서...
<? $this->dojo()->enable()
->requireModule('dojox.json.query')
->onLoadCaptureStart() ?>
function() {
var form = dojo.byId("login_form")
dojo.connect(form, "onsubmit", function(event) {
dojo.stopEvent(event);
var xhrArgs = {
form: this,
handleAs: "json",
load: function(data) {
// assign the new hash to the field
dojo.byId("hash").value = dojox.json.query("$.hash", data);
// some code ..
},
error: function(error) {
// some code ..
}
}
var deferred = dojo.xhrPost(xhrArgs);
});
}
<? $this->dojo()->onLoadCaptureEnd() ?>
너무 늦지 않았으면 좋겠어요 :D
해결책은 다음과 같습니다.
데이터를 포함할 양식 외에 요소가 없는 양식을 만듭니다.컨트롤러에서 두 양식을 인스턴스화합니다.또한 컨트롤러에서 요소 해시를 빈 양식에 추가합니다.두 양식 모두 비전으로 전송해야 합니다.그런 다음 컨트롤러의 "만약 ($request-> isXmlHttpRequest ()" 조건에서 빈 양식을 렌더링합니다.그런 다음 "getValue()" 메서드를 사용하여 해시 값을 가져옵니다.이 값은 Ajax에서 응답으로 보낸 다음 JavaScript를 사용하여 이미 사용되지 않는 해시 값을 대체해야 합니다.해시에 대한 빈 폼을 만드는 옵션은 폼을 렌더링할 때 ID가 다시 생성되고 새 정보를 교체해야 하는 캡차와 같은 다른 요소의 문제를 방지하는 것입니다.두 가지 다른 형태가 있기 때문에 검증은 별도로 진행될 것입니다.나중에 원하는 경우 언제든지 해시(공백) 양식을 다시 사용할 수 있습니다.다음은 코드의 예입니다.
//In the controller, after instantiating the empty form you add the Hash element to it:
$hash = new Zend_Form_Element_Hash('no_csrf_foo');
$hash_form->addElement('hash', 'no_csrf_foo', array('salt' => 'unique'));
//...
//Also in the controller, within the condition "if ($request->isXmlHttpRequest())" you render the form (this will renew the session for the next attempt to send the form) and get the new id value:
$hash_form->render($this->view);
$hash_value['hash'] = $hash_form->getElement('no_csrf_foo')->getValue();//The value must be added to the ajax response in JSON, for example. One can use the methods Zend_Json::decode($response) and Zend_Json::encode($array) for conversions between PHP array and JSON.
//---------------------------------------
//In JavaScript, the Ajax response function:
document.getElementById("no_csrf_foo").value = data.hash;//Retrieves the hash value from the Json response and set it to the hash input.
레오
폼 해시는 원칙적으로 훌륭하고 실제로는 약간 악몽입니다.이것을 처리하는 가장 좋은 방법은 당신이 요청할 때 응답과 함께 새로운 해시를 반환하고, 당신의 자바스크립트를 위해 폼 마크업이나 메모리에 저장하는 것입니다.
새 해시는 양식 개체에서 사용할 수 있거나 세션에서 읽을 수 있습니다.
당신은 당신의 질문에서 정답을 암시했습니다: 홉 카운트를 늘립니다.
온라인 ZF 설명서에 이것에 대한 구체적인 언급이 있었지만, 그들은 설명서를 업데이트했고 지금은 찾을 수 없습니다. 그렇지 않았다면 제가 당신을 위해 링크를 게시했을 것입니다.
Ajax 측면에서 폼 검증기를 사용하려면 다음 코드를 사용합니다.
내 폼 php
class Application_Form_Myform extends Zend_Form
{
# init function & ...
public function generateform($nohash = false)
{
# Some elements
if(!$nohash)
{
$temp_csrf = new Zend_Session_Namespace('temp_csrf');
$my_hash = new Zend_Form_Element_Hash ( 'my_hash' );
$this->addElement ( $my_hash , 'my_hash');
$temp_csrf->hash = $my_hash->getHash();
}
# Some other elements
}
}
AjaxController.php
class AjaxController extends Zend_Controller_Action
{
// init ...
public function validateAction()
{
# ...
$temp_csrf = new Zend_Session_Namespace('temp_csrf');
if($temp_csrf->hash == $params['received_hash_from_client'])
{
$Myform = new Application_Form_Myform();
$Myform->generateform(true);
if($AF_Bill->isValid($params))
{
# Form data is valid
}else{
# Form invalid
}
}else{
# Received hash from client is not valid
}
# ...
}
}
언급URL : https://stackoverflow.com/questions/2474774/how-to-use-zend-framework-form-hash-token-with-ajax
'programing' 카테고리의 다른 글
web.xml의 applicationContext.xml 파일 대신 Spring@Configuration 주석이 달린 클래스를 등록하는 방법은 무엇입니까? (0) | 2023.09.03 |
---|---|
ASP에서 교차 오리진 요청을 활성화하는 방법.NET MVC (0) | 2023.09.03 |
데이터베이스의 자격 증명을 어디에 보관해야 합니까? (0) | 2023.09.03 |
Node.js의 약속 이해 (0) | 2023.09.03 |
Spring REST - ZIP 파일을 생성하여 클라이언트로 전송 (0) | 2023.09.03 |