簡體   English   中英

用戶從支付網關重定向回網站后 CodeIgniter 會話數據丟失

[英]CodeIgniter session data is lost after user is redirected back to the website from payment gateway

我正在使用 CodeIgniter 3 開發一個項目。用戶可以通過預訂頁面上的 paytm 支付網關進行在線支付。

用戶完成付款流程后,他會被重定向回我的網站,該網站由響應控制器處理,我正在使用會話中存儲的預訂 ID 更新預訂詳細信息,例如付款方式和預訂狀態。 當我嘗試在此控制器中訪問會話數據時,會話數據不可用。

這是我的會話配置:

 $config['sess_driver'] = 'files';
 $config['sess_cookie_name'] = 'ci_session';
 $config['sess_expiration'] = 7200;
 $config['sess_save_path'] = BASEPATH . 'cache/sessions/';
 $config['sess_match_ip'] = FALSE;
 $config['sess_time_to_update'] = 300;
 $config['sess_regenerate_destroy'] = FALSE;

這是處理支付網關發送的響應的控制器

public function paytmResponse(){
    $this->load->model('booking_model');
    $this->load->model('user_model');
    $this->load->library('paytm');
    $paytmChecksum = isset($_POST["CHECKSUMHASH"]) ? $_POST["CHECKSUMHASH"] : ""; 
    $this->booking_model->updatePaymentType($_SESSION['bid'], 'online');
    $valid_checksum = $this->paytm->verifyChecksum($_POST, $paytmChecksum);
    if($valid_checksum){
        if($_POST["STATUS"] == "TXN_SUCCESS"){  
            $this->booking_model->savePaymentDetails($_SESSION['bid']);
            $this->booking_model->updateBookingStatus($_SESSION['bid'], 'pending');
            $status = 1; 
        }
        else{
            $this->booking_model->updateBookingStatus($_SESSION['bid'], 'failed');
            $status = 0;
        }
    }
    else{
        $this->booking_model->updateBookingStatus($_SESSION['bid'], 'failed');
        $status = 2;
    }       
    if($status == 1){        
        redirect('booking/success');
    }    
    else{  
        $_SESSION['booking_error'] = 'Payment failed';         
        redirect('booking/failure');
    }
}

我正在使用 codeigniter 會話庫,php 7.2 版

這是一個老問題,但似乎沒有得到適當的解決。 在 CI 3.1.11 中,我重定向到支付網關,當網關完成支付並將控制權返回給會話時,會話變量“丟失”。

事實是他們只是沒有重生。 經過數小時(幾天!!)調查此事並嘗試此處列出的所有選項和其他選項(均無效!),答案在於重新生成會話變量。

如果您的用戶僅通過 LAN 訪問系統,那么您可以通過前兩個步驟逃脫:

  1. 在 system/libraries/Session/Session.php 中注釋掉了 126 - 128 和 130 行。
 //if (!isset($_SESSION['__ci_last_regenerate'])) { // $_SESSION['__ci_last_regenerate'] = time(); //} elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time)) { $this->sess_regenerate((bool) config_item('sess_regenerate_destroy')); //}

這樣做的原因是$_SESSION['__ci_last_regenerate']在第 121 行的session_start()之后沒有恢復。因此$this->sess_regenerate()從未被執行。

  1. 第二步是確保注銷功能正確清除緩存以防止注銷后重新生成:
 function logout() { $this->session->sess_destroy(); $this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate, no-transform, max-age=0, post-check=0, pre-check=0"); $this->output->set_header("Pragma: no-cache"); redirect('logout'); }

如果您的用戶將通過移動或 wifi 網絡訪問,那么您可能需要做更多的工作。 在 PHP 文檔中的 PHP 函數session_regenerate_id() ,它給出了警告:

警告 目前, session_regenerate_id 不能很好地處理不穩定的網絡,例如移動和 WiFi 網絡。 因此,您可能會通過調用 session_regenerate_id 遇到丟失的會話。

所以這就是我所做的:

  1. 找到最后一個會話的session_id 如果您的會話數據存儲在數據庫中,那么以下代碼可能會很好地工作:
 function latestSessionId() { $CI = & get_instance(); $CI->db->reset_query(); $CI->db->select("id")->from($this->_config['save_path'])->order_by('timestamp','desc'); empty($this->config['match_ip']) OR $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); $result = $CI->db->get(); empty($result) OR $result = $result->row(); return empty($result) ? FALSE : $result->id; }
  1. 按照這里的建議然后在 session.php 的第 121 行執行以下操作:
 $session_id = $this->latestSessionId(); session_id($session_id); session_start();
  1. sess_regenerate函數更改為:
 public function sess_regenerate($destroy = FALSE) { $_SESSION['__ci_last_regenerate'] = time(); //session_regenerate_id($destroy); if (session_status() !== PHP_SESSION_ACTIVE) { $session_id = $this->latestSessionId(); session_id($session_id); session_start(); } }
  1. config.php更改為參數sess_expirationsess_time_to_update具有相同的值:
 $config['sess_driver'] = 'database'; $config['sess_cookie_name'] = 'cisession'; $config['sess_expiration'] = 7200; $config['sess_save_path'] = 'ci_sessions'; $config['sess_match_ip'] = TRUE; $config['sess_time_to_update'] = 7200;

這個錯誤可能是我在 Codigniter 4 版本中面臨的那個

在你的 .env 文件中

 cookie.prefix = ''
 cookie.expires = 0
 cookie.path = '/'
 cookie.domain = ''
 cookie.secure = true
 cookie.httponly = false
 cookie.samesite = 'None'
 cookie.raw = false

此錯誤將解決

下面的解決方案在 Codeigniter 中對我來說是正確的。 如果您使用header("Location: $url");重定向支付網關header("Location: $url"); . 只需添加exit(); 在您的標頭重定向之后。 因為您的會話會覆蓋支付網關會話,並且他們會為其支付網關啟動新會話。 添加exit(); 只要您的會話有效,您的域的會話將保持不變。 最終代碼將是

header("Location: $url");exit();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM