Search code examples
opencartopencart-3

I am using opencart 3 browser close customer logout, how to stop customer logout even browser is close


I am using opencart 3 my issue is that when customer close browser and open again customer is logout, i want to change this behavior, i need when customer once login he/she should not logout until he/she click logout button, even if he/she close the browser and open again he/she should remain login.


Solution

  • You have to modify 3 files in OpenCart to accomplish this.

    /catalog/controller/account/login.php

    During login process, you have to store customer ID and email in cookie. It worth to store them encrypted. Email is not enough, because you have to check that stored customer ID belongs to stored email.

      public function index() {
        [...]
        if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
          // Unset guest
          unset($this->session->data['guest']);
    
          // store customer ID and email encrypted
          $my_customer_id = $this->customer->getId();
          $my_customer_id_crypted = $this->encrypt($my_customer_id, "your_key_for_customer_id_encryption");
    
          $my_email = $this->request->post['email'];
          $my_email_crypted = $this->encrypt($this->request->post['email'], "your_key_for_email_encryption");
    
          setcookie("MyCustomerID", $my_customer_id_crypted , time() + (365 * 24 * 60 * 60) , "/");
          setcookie("MyEmail", $my_email_crypted , time() + (365 * 24 * 60 * 60) , "/");
          [...]
        }
        [...]
      }
    
      [...]
    
      // https://www.phpcluster.com/simple-two-way-encryption-in-php/
      // you can use other encryption if you want, just an example
      protected function encrypt($plainText, $key) {
        $secretKey = md5($key);
        $iv = substr( hash( 'sha256', "aaaabbbbcccccddddeweee" ), 0, 16 );
        $encryptedText = openssl_encrypt($plainText, 'AES-128-CBC', $secretKey, OPENSSL_RAW_DATA, $iv);
        return base64_encode($encryptedText);
      }
    

    /catalog/controller/account/logout.php

    During logout process, you have to delete customer ID and email cookies

      public function index() {
        if ($this->customer->isLogged()) {
          $this->customer->logout();
    
          // delete cookies
          unset($_COOKIE['MyCustomerID']);
          unset($_COOKIE['MyEmail']);
    
          setcookie("MyCustomerID", "", 0, "/");
          setcookie("MyEmail", "", 0, "/");
          [...]
        }
        [...]
      }
    

    /catalog/controller/common/footer.php

    In this file you can auto login customer if everything is OK and extend cookie lifetime, footer is used on every page load so it is a good way I mean

      public function index() {
        [...]
        $data['scripts'] = $this->document->getScripts('footer');
        $data['styles'] = $this->document->getStyles('footer');
    
        if (isset($_COOKIE["MyCustomerID"]) && isset($_COOKIE["MyEmail"]) && $_COOKIE["MyCustomerID"] != '' && $_COOKIE["MyEmail"] != '') {
          $my_customer_id_crypted = $_COOKIE["MyCustomerID"];
          $my_customer_id = $this->decrypt($my_customer_id_crypted, "your_key_for_customer_id_encryption");
    
          $my_email_crypted = $_COOKIE["MyEmail"];
          $my_email = $this->decrypt($my_email_crypted, "your_key_for_email_encryption");
    
          $config = new Config();
          $config->load('default');
    
          if ( $my_customer_id != "" && $my_email != "" && $my_customer_id == (int)$my_customer_id ) {
            if ( !$this->customer->isLogged() ) {          
              if ( $my_customer_id == $this->getCustomerIdByEmailAddress( $my_email ) ) { // auto login, when customer ID belongs to this email address
                $this->customer->login($my_email, "", true); // we use OpenCart override log in method
                //$this->log->write('customer logged in automatically');
    
                $this->load->model('account/address');
    
                if ($this->config->get('config_tax_customer') == 'payment') {
                  $this->session->data['payment_address'] = $this->model_account_address->getAddress($this->customer->getAddressId());
                }
    
                if ($this->config->get('config_tax_customer') == 'shipping') {
                  $this->session->data['shipping_address'] = $this->model_account_address->getAddress($this->customer->getAddressId());
                }
    
                // extend cookies lifetime
                setcookie("MyCustomerID", $my_customer_id_crypted , time() + (365 * 24 * 60 * 60) , "/");
                setcookie("MyEmail", $my_email_crypted , time() + (365 * 24 * 60 * 60) , "/");
    
                $this->response->redirect($_SERVER['REQUEST_URI']);
              }
            }
          }
        }
        [...]
      }
    
      // https://www.phpcluster.com/simple-two-way-encryption-in-php/
      // decrypt function for previous used encryption
      protected function decrypt($encryptedText, $key) {
        $key = md5($key);
        $iv = substr( hash( 'sha256', "aaaabbbbcccccddddeweee" ), 0, 16 );
        $decryptedText = openssl_decrypt(base64_decode($encryptedText), 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
        return $decryptedText;
      }
    
      protected function getCustomerIdByEmailAddress($email) {
        $sql_txt = "";
        $sql_txt .= "SELECT customer_id";
        $sql_txt .= "  FROM ".DB_PREFIX."customer";
        $sql_txt .= " WHERE LOWER(email) = '".$this->db->escape(utf8_strtolower($email))."'";
        $customer_query = $this->db->query($sql_txt);
    
        if ($customer_query->num_rows)
        {
          return $customer_query->row['customer_id'];
        }
        else
        {
          return -1;
        }
      }
    

    You can refine this code if you want, currently I use this method to auto login customer