我已经创建了登录表单并使用 csrf 令牌,如果我发送第一个请求,它将正确验证。现在我尝试使用错误的密码,而不是从服务器收到新的 csrf 令牌。当我再次使用正确的密码重新发送请求时,它将显示错误 403。
这是我的代码。 1.查看文件
<form action="<?=$module."/validate_login"?>" id="form" name="form">
<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />
<div class="mb-4">
<label class="mb-1 text-dark">Email</label>
<input type="email" class="form-control form-control" id="username" name="username"
placeholder="[email protected]">
<div class="invalid-feedback"></div>
</div>
<div class="mb-4 position-relative">
<label class="mb-1 text-dark">Password</label>
<input type="password" id="dz-password" name="password" class="form-control"
placeholder="Password">
<span class="show-pass eye">
<i class="fa fa-eye-slash"></i>
<i class="fa fa-eye"></i>
</span>
<div class="invalid-feedback"></div>
</div>
<div class="form-row d-flex justify-content-between mt-4 mb-2">
<div class="mb-4">
<div class="form-check custom-checkbox mb-3">
<input type="checkbox" class="form-check-input" id="customCheckBox1">
<label class="form-check-label" for="customCheckBox1">Remember my
preference</label>
</div>
</div>
<div class="mb-4">
<a href="<?=base_url("forgot-password")?>" class="btn-link text-primary">Forgot
Password?</a>
</div>
</div>
<div class="text-center mb-4">
<button type="submit" class="btn btn-primary btn-block">Sign In</button>
</div>
<div class="form-row" id="alert-message" style="display: none;">
<div class="alert alert-danger alert-dismissible fade show">
<button type="button" class="btn-close" data-bs-dismiss="alert"
aria-label="btn-close"><span><i class="fa-solid fa-xmark"></i></span>
</button>
<strong>Error!</strong> In-valid username or password.
</div>
</div>
</form>
2 . JS 文件
$("#form").validate({
rules : {
username : 'required',
password : 'required'
},
messages : {
username : 'Please enter e-mail',
password : 'Please enter password'
},
submitHandler : function(form,e){
e.preventDefault();
var form_data = new FormData(form);
$.ajax({
url : SITE_URL+"validate-login",
type : "POST",
contentType: false,
cache: false,
processData:false,
data : form_data,
beforeSend : function(){
},
success : function(response){
$('.txt_csrfname').val(response.data.token);
if(response.success == "1"){
$("#alert-message").css("display","none");
window.location.href= SITE_URL+"Dashboard";
}else{
console.log(response.data.token);
$("#alert-message").css("display","");
}
},
error : function(){
}
});
}
});
控制器
公共函数 validate_login(){
$request = service('request');
$requestArr = $request->getPost();
$responseArr = array("success"=>"1","data"=>array(),"message"=>"");
$data = array();
$data['token'] = csrf_hash();
$ipaddress = $this->request->getIPAddress();
$rules = [
'username' => 'required|valid_email',
'password' => 'required'
];
if($this->validate($rules)){
$userArr = $this->Auth->login($requestArr['username']);
if(!empty($userArr)) {
$verify_password = password_verify($requestArr['password'],$userArr->password);
if($verify_password){
$responseArr['success'] = "1";
$responseArr['message'] = "Loged in successfully.";
$this->session->set([
'tbl_users_id'=>$userArr->tbl_users_id,
'full_name'=>$userArr->full_name,
'username'=>$userArr->username,
'email'=>$userArr->email
]);
$logArr = array(
'user_id' => $userArr->tbl_users_id,
'module' => $this->module,
'module_id' => $userArr->tbl_users_id,
'action' => "LOGIN",
'ip_address' => $ipaddress,
'remarks' => "User Loged In",
'raw_data'=> ""
);
insert_log($logArr);
}else{
$responseArr['success'] = "0";
$responseArr['message'] = "In-valid username or password.";
}
}else{
$responseArr['success'] = "0";
$responseArr['message'] = "In-valid username or password.";
}
}else{
$responseArr['message']= "Required Fields are missing";
}
$responseArr['data']= $data;
output($responseArr);
}
它只会在第一次调用时验证 CSRF 令牌。 之后就会显示403错误。 想要通过所有 ajax 请求验证 csrf 令牌。
我不是 100% 确定,但如果您使用 ajax 进行表单提交,您可以将数据作为 JSON 发送,或为您的请求设置任何自定义标头。那么您无需担心任何 CSFR。
还可以看看 axios 库,它可以同时执行这两个操作。
而是与具有更好安全知识的人确认。