Nasir
Nasir

Reputation: 431

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.

Upvotes: 0

Views: 491

Answers (1)

Baracsi Róbert
Baracsi Róbert

Reputation: 61

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

Upvotes: 1

Related Questions