php - 如果已经使用另一个会话登录,则会中断登录流程
问题描述
我正在开发一个 codeigniter 3 应用程序,我最近实现了一个会话检查器,如果用户已经登录,它会删除用户会话。现在,如果用户已经使用另一个会话登录,我们希望弹出一个模式框。我可以使用按钮弹出一个模式框,但我想将它实现到登录系统的原始流程中。因为它是登录表单,所以您可以直接进入验证登录系统。这是现在的登录表单:
<form action="<?php echo site_url('login/validate_login/user'); ?>" method="post">
<div class="content-box">
<div class="basic-group">
<div class="form-group">
<label for="login-email"><span class="input-field-icon"><i class="fas fa-envelope"></i></span> <?php echo get_phrase('email'); ?>:</label>
<input type="email" class="form-control" name = "email" id="login-email" placeholder="<?php echo get_phrase('email'); ?>" value="" required>
</div>
<div class="form-group">
<label for="login-password"><span class="input-field-icon"><i class="fas fa-lock"></i></span> <?php echo get_phrase('password'); ?>:</label>
<input type="password" class="form-control" name = "password" placeholder="<?php echo get_phrase('password'); ?>" value="" required>
</div>
</div>
</div>
<div class="content-update-box">
<button type="submit" class="btn"><?php echo get_phrase('login'); ?></button>
</div>
<!-- Modal -->
<div class="modal fade" id="login" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">You are already logged in</h4>
</div>
<div class="modal-body">
<p>You are currently logged in on a different session on the site. Please note that if you continue, the existing session will be terminated. Please change your password if you suspect that your account has been conpromised.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel Login</button>
<button type="submit" class="btn"><?php echo get_phrase('login'); ?></button>
</div>
</div>
</div>
</div>
<div class="forgot-pass text-center">
<span><?php echo get_phrase('or'); ?></span>
<a href="javascript::" onclick="toggoleForm('forgot_password')"><?php echo get_phrase('forgot_password'); ?></a>
</div>
<div class="account-have text-center">
<?php echo get_phrase('do_not_have_an_account'); ?>? <a href="javascript::" onclick="toggoleForm('registration')"><?php echo get_phrase('sign_up'); ?></a>
</div>
</form>
此刻的按钮直接进入这个登录功能:
public function validate_login($from = "") {
$email = $this->input->post('email');
$password = $this->input->post('password');
$credential = array('email' => $email, 'password' => sha1($password), 'status' => 1);
// Checking login credential for admin
$query = $this->db->get_where('users', $credential);
if ($query->num_rows() > 0) {
$row = $query->row();
$this->session->set_userdata('user_id', $row->id);
$this->session->set_userdata('role_id', $row->role_id);
$this->session->set_userdata('role', get_user_role('user_role', $row->id));
$this->session->set_userdata('name', $row->first_name.' '.$row->last_name);
$this->delete_session_user_id();
$this->session->set_flashdata('flash_message', get_phrase('welcome').' '.$row->first_name.' '.$row->last_name);
if ($row->role_id == 1) {
$this->session->set_userdata('admin_login', '1');
redirect(site_url('admin/dashboard'), 'refresh');
}else if($row->role_id == 2){
$this->session->set_userdata('user_login', '1');
$this->set_session_user_id();
redirect(site_url('home/my_courses'), 'refresh');
}
}else {
$this->session->set_flashdata('error_message',get_phrase('invalid_login_credentials'));
redirect(site_url('home/login'), 'refresh');
}
}
我创建了这个函数来从电子邮件中提取用户 ID:
public function get_user_id($user_email = "") {
$this->db->select('id');
$this->db->where('email', $user_email);
$user_id=$this->db->get('users');
return $user_id;
}
此函数可以根据提供的电子邮件获取用户 ID。
然后我使用这个函数来检查是否存在会话,如果有 0 个结果则返回false ,如果存在具有该用户 ID 的会话,则返回true 。因此,如果它是假的,他们应该能够登录并且模式弹出窗口不应该打开,但如果它是真的,它应该打开。
public function user_has_session($user_id=''){
$this->db->where('user_id',$user_id);
$this->db->from('ci_sessions');
$total=$this->db->count_all_results();
if($total<0)
return false;
else
return true;
}
我认为这是无需重做整个登录流程的最佳方法。也许有人可以建议这是否是最好的方法,或者实际上我是否应该改变整个流程。
谢谢
这是我自己回答的上一个问题 https://stackoverflow.com/questions/62458226/codeigniter-3-stop-multiple-logins-using-ci-sessions-database
更新添加以澄清我的问题
那么问题是当尝试从另一个设备登录时,它应该注销另一个活动会话。因此,如果在我的桌面上使用新的浏览器或什至使用相同的用户 ID 登录我的手机,则活动会话应该结束,此时它会在没有警告用户的情况下结束。所以我想要一个模式弹出警告用户当前正在使用这个用户 ID 运行一个活动会话
解决方案
您需要实现一个 Ajax 调用,该调用将检查用户是否已经登录。如果用户未登录,则您可以继续登录,否则会触发您的弹出窗口打开以显示消息。
在这里用户可以选择是否登录,如果用户选择登录,那么您可以在提交时取消绑定事件并让用户继续。
我对您的 HTML 文件进行了一些更改。请检查以下 -
您的 HTML 模板
<form action="<?php echo site_url('login/validate_login/user'); ?>" id="login-form" onSubmit="return checkUserSession();" method="post">
<div class="content-box">
<div class="basic-group">
<div class="form-group">
<label for="login-email"><span class="input-field-icon"><i class="fas fa-envelope"></i></span> <?php echo get_phrase('email'); ?>:</label>
<input type="email" class="form-control" name = "email" id="login-email" placeholder="<?php echo get_phrase('email'); ?>" value="" required>
</div>
<div class="form-group">
<label for="login-password"><span class="input-field-icon"><i class="fas fa-lock"></i></span> <?php echo get_phrase('password'); ?>:</label>
<input type="password" class="form-control" name = "password" placeholder="<?php echo get_phrase('password'); ?>" value="" required>
</div>
</div>
</div>
<div class="content-update-box">
<button type="submit" class="btn"><?php echo get_phrase('login'); ?></button>
</div>
<!-- Modal -->
<div class="modal fade" id="login" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">You are already logged in</h4>
</div>
<div class="modal-body">
<p>You are currently logged in on a different session on the site. Please note that if you continue, the existing session will be terminated. Please change your password if you suspect that your account has been conpromised.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel Login</button>
<button type="button" id="modal-submit-button" class="btn"><?php echo get_phrase('login'); ?></button>
</div>
</div>
</div>
</div>
<div class="forgot-pass text-center">
<span><?php echo get_phrase('or'); ?></span>
<a href="javascript::" onclick="toggoleForm('forgot_password')"><?php echo get_phrase('forgot_password'); ?></a>
</div>
<div class="account-have text-center">
<?php echo get_phrase('do_not_have_an_account'); ?>? <a href="javascript::" onclick="toggoleForm('registration')"><?php echo get_phrase('sign_up'); ?></a>
</div>
</form>
<script>
/** Trigger function on form submit whether to check user logged in */
function checkUserSession(){
var email = $("#login-email").val();
$.ajax({
url: "<?php echo site_url('login/checkUserSession'); ?>",
type: 'POST',
data: { 'email': email},
success: function(status){
if(status == true) { // User is already logged in somewhere, display the messege.
$("#login").modal();
return false;
} else { // User is not logged in, submit the form
return true;
}
}
});
}
/** Allow user to log in with exception */
$("#modal-submit-button").on("click", function(){
$("#login").modal('hide'); // hide the modal
$("#login-form").attr("onSubmit", ""); // unbind the function
$("#login-form").submit(); // submit login form
})
</script>
控制器-
<?php
/** Function to check user logged in or not */
public function checkUserSession() {
$user_email = $this->input->post('email');
$userId = $this->get_user_id($user_email);
$response = $this->user_has_session($userId);
echo $response;
}
public function get_user_id($user_email = "") {
$this->db->select('id');
$this->db->where('email', $user_email);
$user_id=$this->db->get('users');
return $user_id;
}
public function user_has_session($user_id=''){
$this->db->where('user_id',$user_id);
$this->db->from('ci_sessions');
$total=$this->db->count_all_results();
if($total<0)
return false;
else
return true;
}
?>
推荐阅读
- r - 如何在使用不同大小的数据时在同一图中绘制线和点
- spring-boot - 使用 Spring Boot 在运行时加载 Yml
- reactjs - Antd 中的 Markdown
- python - 在heroku上初始化Flask-SocketIO python应用
- javascript - 显示来自ajax的数据后阅读更多和更少不起作用
- laravel - 在一条记录中导入多个 id
- node.js - 是否可以在不安装模块的情况下在 NodeJS 中使用 DigestAuthentidfication?
- python - 内存未释放,即使对象引用计数为 0
- scala - DataFrame如何在包含多维数组的列中添加
- javascript - 从元素中获取文本