首页 > 解决方案 > 如果已经使用另一个会话登录,则会中断登录流程

问题描述

我正在开发一个 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 运行一个活动会话

标签: phpcodeigniterauthentication

解决方案


您需要实现一个 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;
        }
    ?>

推荐阅读