在 Phalcon 中使用 Ajax 的 CSRF 保护服务
Using CSRF Protection Service with Ajax in Phalcon
我在 Ajax 的 Phalcon 中遇到 CSRF 保护组件的问题。
html形式
<form id="signup-form" onSubmit="onSignUpSubmit(); return false;">
<input id="username" type="text" placeholder="Username" />
<input id="password" type="password" placeholder="Password" />
<input id="email" type="text" placeholder="Email" />
<input id="signup-csrf-token" name="{{ security.getTokenKey() }}" val="{{ security.getToken() }}" type="hidden" />
<button class="btn btn-primary btn-block" type="submit">Sign Up</button>
</form> <!-- #signup-form -->
Ajax代码
var username = $('#username', '#signup-form').val(),
password = $('#password', '#signup-form').val(),
email = $('#email', '#signup-form').val(),
csrfKey = $('#signup-csrf-token').attr('name'),
csrfValue = $('#signup-csrf-token').attr('val');
var postData = {
'username': username,
'password': password,
'email': email
};
postData[csrfKey] = csrfValue;
$.ajax({
type: 'POST',
url: '{{ url('/accounts/signup.action') }}',
data: postData,
dataType: 'JSON',
success: function(result){
console.log(result);
}
});
第一次发送Ajax请求时,Controller中的$this->security->checkToken()
函数returns为真。但是第二次及以后,函数 returns false.
我认为每个 HTTP 请求的 csrfToken
更改导致了这个问题。但是怎么解决呢?
谁能帮帮我?
您需要在 AJAX 成功响应中 return 新的 CSRF 令牌。然后使用新令牌更新您的表单字段。
accounts/signup.action
return json_encode((object) array(
'output' => $original_output,
'csrf' => (object) array('name' => $csrf_name, 'value' => $csrf_token)
));
Javascript
$.ajax({
type: 'POST',
url: '{{ url('/accounts/signup.action') }}',
data: postData,
dataType: 'JSON',
success: function(result){
$('input#signup-csrf-token')
.attr('name', result.csrf.name)
.val(result.csrf.value);
console.log(result.output);
}
});
你也应该改变
$('#signup-csrf-token').attr('val');
到
$('#signup-csrf-token').val();
我在 Ajax 的 Phalcon 中遇到 CSRF 保护组件的问题。
html形式
<form id="signup-form" onSubmit="onSignUpSubmit(); return false;">
<input id="username" type="text" placeholder="Username" />
<input id="password" type="password" placeholder="Password" />
<input id="email" type="text" placeholder="Email" />
<input id="signup-csrf-token" name="{{ security.getTokenKey() }}" val="{{ security.getToken() }}" type="hidden" />
<button class="btn btn-primary btn-block" type="submit">Sign Up</button>
</form> <!-- #signup-form -->
Ajax代码
var username = $('#username', '#signup-form').val(),
password = $('#password', '#signup-form').val(),
email = $('#email', '#signup-form').val(),
csrfKey = $('#signup-csrf-token').attr('name'),
csrfValue = $('#signup-csrf-token').attr('val');
var postData = {
'username': username,
'password': password,
'email': email
};
postData[csrfKey] = csrfValue;
$.ajax({
type: 'POST',
url: '{{ url('/accounts/signup.action') }}',
data: postData,
dataType: 'JSON',
success: function(result){
console.log(result);
}
});
第一次发送Ajax请求时,Controller中的$this->security->checkToken()
函数returns为真。但是第二次及以后,函数 returns false.
我认为每个 HTTP 请求的 csrfToken
更改导致了这个问题。但是怎么解决呢?
谁能帮帮我?
您需要在 AJAX 成功响应中 return 新的 CSRF 令牌。然后使用新令牌更新您的表单字段。
accounts/signup.action
return json_encode((object) array(
'output' => $original_output,
'csrf' => (object) array('name' => $csrf_name, 'value' => $csrf_token)
));
Javascript
$.ajax({
type: 'POST',
url: '{{ url('/accounts/signup.action') }}',
data: postData,
dataType: 'JSON',
success: function(result){
$('input#signup-csrf-token')
.attr('name', result.csrf.name)
.val(result.csrf.value);
console.log(result.output);
}
});
你也应该改变
$('#signup-csrf-token').attr('val');
到
$('#signup-csrf-token').val();