在第二个 POST 请求中避免 codeigniter 中的错误 403
Avoid error 403 in codeigniter on a second POST request
我不明白为什么我不能在不刷新页面的情况下执行多个请求。
任何请求都可以正常工作,但是如果我需要执行另一个请求(不管是否相同)...我不能!我需要刷新页面来做一个新的请求,否则,我会得到错误 403。
所有代码都在工作,只是,任何请求都以刷新页面结束。我不喜欢那样,因为我认为它不专业。
我需要在 codeigniter 中更改什么才能在不刷新页面的情况下允许多个请求?
评论更新:我使用 csrf 保护,我不想禁用它。
@Vickel 这是其中一个请求(所有请求都几乎相同,只是 url 和数据)...没有表格。
function set_tracking(order_id)
{
$.ajax({
type: "POST",
data: {
order_id: order_id
},
url: trackingURL,
beforeSend: function() {
$('.lds-default').removeClass('hidden');
},
success: function (response) {
console.log(response);
if(response.error)
{
show_form_errors(lang['productions_error_not_set_tracking']);
} else {
$('#set_tracking .modal-title').html(lang['productions_set_tracking_title']);
$('#set_tracking').modal('show');
$('#set_tracking #order_id').val(order_id);
}
},
error: function (event) {
if (event.status !== 401) {
show_form_errors(lang['companies_error_deleting_segment']);
}
},
complete: function() {
$('#confirm_message').modal('hide');
$('.lds-default').addClass('hidden');
}
});
}
您遇到了过期的 CSRF 令牌。有多种解决方法(每种方法都有不同的复杂性和安全级别)
1.- 完全禁用 CSRF(不推荐,除非您的所有表单都位于每个人都登录的安全区域内,并且无法获得跨域请求,这是不太可能的。
2.- 定义 CSRF 功能的例外情况。在 application/config/config.php
中,您会找到一个名为 $config['csrf_exclude_uris']
的数组,您可以在其中添加您希望不对其执行 CSRF 检查的所有 controller/method 对
3.- 禁用 CSRF 再生。在 application/config/config.php
中,您可以将 $config['csrf_regenerate']
设置为 false
。这将防止在每次请求后重新生成 CSRF 令牌,这将允许您进行多次提交而不会被 CSRF 检查阻止
4.- 第一次提交后手动获取重新生成的令牌,并与第二次提交一起传递。这是解决问题的最安全方法,但也是最复杂的方法。您可以在 Codeigniter's Security Class documentation here
中深入了解这一点
为了手动重新生成 CSRF 令牌,您可以执行以下操作:
- 在您的视图中创建一个隐藏的输入字段,用于存储您的 csrf 令牌
- 在您的控制器中,您创建一个新令牌并将其与您的 ajax 响应一起发回
- 在您的 ajax 成功功能中,您更新隐藏的输入字段
现在您可以发送新请求了
查看:
<?php
$csrf = array(
'name' => $this->security->get_csrf_token_name(),
'hash' => $this->security->get_csrf_hash()
);
?>
<input type="hidden" name="<?=$csrf['name'];?>" value="<?=$csrf['hash'];?>" />
javascript:
tn='<?php echo $this->security->get_csrf_token_name(); ?>';
th=$('input[name="'+tn+'"]').val();
csfrData={tn:th};
$.ajax({
type: "POST",
dataType:json,
data: {
order_id: order_id,
csrf:csfrData // send current token
},
//etc...
success: function (response) {
// update hidden input field with new token
$('input[name="'+response.csrf.csrf_name+'"]').val(response.csrf.csrf_hash)
// etc
}
})
控制器:
function your_tracking_url(){
$data['yourdata']=array() // whatever you return
$data['csrf']=$this->get_csrf();
echo json_encode($data);
}
function get_csrf(){
// creating a new token
$csrf=array('csrf_name'=>$this->security->get_csrf_token_name(),'csrf_hash'=>$this->security->get_csrf_hash());
return $csrf;
}
您可能需要稍微调整一下,但它展示了手动 csrf 令牌重新生成的概念
我不明白为什么我不能在不刷新页面的情况下执行多个请求。
任何请求都可以正常工作,但是如果我需要执行另一个请求(不管是否相同)...我不能!我需要刷新页面来做一个新的请求,否则,我会得到错误 403。
所有代码都在工作,只是,任何请求都以刷新页面结束。我不喜欢那样,因为我认为它不专业。
我需要在 codeigniter 中更改什么才能在不刷新页面的情况下允许多个请求?
评论更新:我使用 csrf 保护,我不想禁用它。
@Vickel 这是其中一个请求(所有请求都几乎相同,只是 url 和数据)...没有表格。
function set_tracking(order_id)
{
$.ajax({
type: "POST",
data: {
order_id: order_id
},
url: trackingURL,
beforeSend: function() {
$('.lds-default').removeClass('hidden');
},
success: function (response) {
console.log(response);
if(response.error)
{
show_form_errors(lang['productions_error_not_set_tracking']);
} else {
$('#set_tracking .modal-title').html(lang['productions_set_tracking_title']);
$('#set_tracking').modal('show');
$('#set_tracking #order_id').val(order_id);
}
},
error: function (event) {
if (event.status !== 401) {
show_form_errors(lang['companies_error_deleting_segment']);
}
},
complete: function() {
$('#confirm_message').modal('hide');
$('.lds-default').addClass('hidden');
}
});
}
您遇到了过期的 CSRF 令牌。有多种解决方法(每种方法都有不同的复杂性和安全级别)
1.- 完全禁用 CSRF(不推荐,除非您的所有表单都位于每个人都登录的安全区域内,并且无法获得跨域请求,这是不太可能的。
2.- 定义 CSRF 功能的例外情况。在 application/config/config.php
中,您会找到一个名为 $config['csrf_exclude_uris']
的数组,您可以在其中添加您希望不对其执行 CSRF 检查的所有 controller/method 对
3.- 禁用 CSRF 再生。在 application/config/config.php
中,您可以将 $config['csrf_regenerate']
设置为 false
。这将防止在每次请求后重新生成 CSRF 令牌,这将允许您进行多次提交而不会被 CSRF 检查阻止
4.- 第一次提交后手动获取重新生成的令牌,并与第二次提交一起传递。这是解决问题的最安全方法,但也是最复杂的方法。您可以在 Codeigniter's Security Class documentation here
中深入了解这一点为了手动重新生成 CSRF 令牌,您可以执行以下操作:
- 在您的视图中创建一个隐藏的输入字段,用于存储您的 csrf 令牌
- 在您的控制器中,您创建一个新令牌并将其与您的 ajax 响应一起发回
- 在您的 ajax 成功功能中,您更新隐藏的输入字段
现在您可以发送新请求了
查看:
<?php
$csrf = array(
'name' => $this->security->get_csrf_token_name(),
'hash' => $this->security->get_csrf_hash()
);
?>
<input type="hidden" name="<?=$csrf['name'];?>" value="<?=$csrf['hash'];?>" />
javascript:
tn='<?php echo $this->security->get_csrf_token_name(); ?>';
th=$('input[name="'+tn+'"]').val();
csfrData={tn:th};
$.ajax({
type: "POST",
dataType:json,
data: {
order_id: order_id,
csrf:csfrData // send current token
},
//etc...
success: function (response) {
// update hidden input field with new token
$('input[name="'+response.csrf.csrf_name+'"]').val(response.csrf.csrf_hash)
// etc
}
})
控制器:
function your_tracking_url(){
$data['yourdata']=array() // whatever you return
$data['csrf']=$this->get_csrf();
echo json_encode($data);
}
function get_csrf(){
// creating a new token
$csrf=array('csrf_name'=>$this->security->get_csrf_token_name(),'csrf_hash'=>$this->security->get_csrf_hash());
return $csrf;
}
您可能需要稍微调整一下,但它展示了手动 csrf 令牌重新生成的概念