AI编程助手
AI免费问答

解决回调URL页面Session ID频繁变更的问题

花韻仙語   2025-08-25 22:44   385浏览 原创

 解决回调URL页面Session ID频繁变更的问题

### 摘要 本文针对在API回调场景下,Session ID在回调URL页面发生变化,导致无法正确关联请求与回调数据的问题,提出了一种解决方案。问题源于Session机制的特性,即Session ID可能在不同页面或请求中发生变化。为了解决这个问题,建议使用Cookie来存储一个唯一的ID,并在回调URL中使用该Cookie值,从而保证ID的稳定性和一致性,实现请求与回调数据的正确关联。 ### 问题分析 在Web开发中,Session通常用于在服务器端存储用户会话信息。Session ID是用于标识每个用户会话的唯一标识符。然而,Session ID并非始终保持不变,在某些情况下,例如跨域请求、不同的子域名或服务器配置等,Session ID可能会发生变化。 在你的场景中,`processor.php`页面发起API请求,并设置了回调URL `response.php`。当API服务器将响应发送到`response.php`时,`response.php`页面可能会生成一个新的Session ID,导致无法通过Session ID关联`processor.php`页面发起的请求。 ### 解决方案:使用Cookie替代Session 为了解决Session ID变更的问题,建议使用Cookie来存储一个唯一的ID,并在回调URL中使用该Cookie值。Cookie是存储在客户端浏览器中的小型文本文件,可以在不同的页面和请求之间共享。 **步骤 1: 生成并设置Cookie** 在`processor.php`页面中,生成一个唯一的ID,例如使用`uniqid()`函数,并将其存储到Cookie中。 ```php <?php // processor.php session_start(); include_once "db.te.php"; // 生成唯一ID $unique_id = uniqid(); // 设置Cookie,有效期为30分钟 setcookie("my_unique_id", $unique_id, time() + (30 * 60), "/"); // 其他代码...

步骤 2: 在回调url中使用cookie

在response.php页面中,获取Cookie中存储的ID,并将其用于关联数据。

<?php
// response.php
include_once "db.te.php";

// 获取Cookie中的ID
if (isset($_COOKIE["my_unique_id"])) {
    $unique_id = $_COOKIE["my_unique_id"];
} else {
    // Cookie不存在,处理错误
    error_log("Cookie 'my_unique_id' not found in response.php");
    exit;
}

// 其他代码...

步骤 3: 修改数据库操作

在数据库中,使用Cookie中的ID作为关联键,替代原来的Session ID。在processor.php中插入数据时,将$unique_id存入数据库,在response.php中查询数据时,也使用$unique_id作为查询条件。

示例代码:修改后的processor.php

<?php
// processor.php
session_start();
include_once "db.te.php";

// 生成唯一ID
$unique_id = uniqid();

// 设置Cookie,有效期为30分钟
setcookie("my_unique_id", $unique_id, time() + (30 * 60), "/");

// if (isset($_POST['submit'])) {

date_default_timezone_set('Africa/Nairobi');

$Passkey = 'bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919';

$Amount= $_POST['amount'];
$BusinessShortCode = '174379';
$PartyA =$_POST['phone'];
$AccountReference =$_POST['name'];
$TransactionDesc = 'test';
$Timestamp =date('YmdHis');
$Password = base64_encode($BusinessShortCode.$Passkey.$Timestamp);
$headers=['Content-Type:application/json; charset=utf8'];
$initiate_url='https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest';
$callBackURL ='https://c28d-197-231-178-65.ngrok.io/textEditor/response.php';
// ------------------------------

function newAccessToken() {
    $ConsumerKey = 'uhsjjsjbVGatHuJKK';
    $ConsumerSecret = 'Yh29KHAY17LKjahh';
    $credentials = base64_encode($ConsumerKey.":".$ConsumerSecret);
    $url = "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials";
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic ".$credentials,"Content-Type:application/json"));
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $curl_response = curl_exec($curl);
    $access_token=json_decode($curl_response);
    curl_close($curl);
    return $access_token->access_token;
}

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $initiate_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.newAccessToken()));
$curl_post_data = array(
    'BusinessShortCode' =>$BusinessShortCode,
    'Password' => $Password,
    'Timestamp' => $Timestamp,
    'TransactionType' => 'CustomerPayBillOnline',
    'Amount' => $Amount,
    'PartyA' => $PartyA,
    'PartyB' => $BusinessShortCode,
    'PhoneNumber' => $PartyA,
    'CallBackURL' => $callBackURL,
    'AccountReference' => $AccountReference,
    'TransactionDesc' => $TransactionDesc
);

$data_string = json_encode($curl_post_data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
$curl_response = curl_exec($curl);

curl_close($curl);

// 在数据库中插入$unique_id
$sql = "INSERT INTO duka (/* 其他字段 */, UniqueId) VALUES (/* 其他值 */, '$unique_id');";
// }
?>

示例代码:修改后的response.php

<?php
// response.php
include_once "db.te.php";

// 获取Cookie中的ID
if (isset($_COOKIE["my_unique_id"])) {
    $unique_id = $_COOKIE["my_unique_id"];
} else {
    // Cookie不存在,处理错误
    error_log("Cookie 'my_unique_id' not found in response.php");
    exit;
}

$homepage =  file_get_contents('php://input');
$nowNow = json_decode($homepage);

if ($nowNow->Body->stkCallback->ResultCode==0) {
    $Items = $nowNow->Body->stkCallback->CallbackMetadata->Item;
    foreach($Items as $Item) {
        if ($Item->Name =='MpesaReceiptNumber') {
            $MpesaReceiptNumber = $Item->Value;
        }
    }
}else{
    $ResultCode = $nowNow->Body->stkCallback->ResultCode;
    $MerchantRequestID =  $nowNow->Body->stkCallback->MerchantRequestID;
    $CheckoutRequestID = $nowNow->Body->stkCallback->CheckoutRequestID;
    $ResultDesc = $nowNow->Body->stkCallback->ResultDesc;
    $sql = "SELECT * FROM duka;";

    $stmt = mysqli_stmt_init($conn);

    if (!mysqli_stmt_prepare($stmt, $sql)) {
        echo "SQL statement failed 1!";

    }else{
        mysqli_stmt_execute($stmt);
        $result = mysqli_stmt_get_result($stmt);
        $rowCount = mysqli_num_rows($result);

        // 使用$unique_id作为查询条件
        $sql = "INSERT INTO duka(ResultCode, MerchantReqID, CheckoutReqID, ResultDesc, UniqueId) VALUES (?,?,?,?,?);";

        if (!mysqli_stmt_prepare($stmt, $sql)) {
            echo "SQL statement failed 2!";

        }else{
            mysqli_stmt_bind_param($stmt,"sssss", $ResultCode, $MerchantRequestID,$CheckoutRequestID,$ResultDesc,$unique_id);

            mysqli_stmt_execute($stmt);
        }
    }

}
?>

示例代码:修改后的fromdb.php

<?php
include_once "db.te.php";

// 获取Cookie中的ID
if (isset($_COOKIE["my_unique_id"])) {
    $unique_id = $_COOKIE["my_unique_id"];
} else {
    // Cookie不存在,处理错误
    error_log("Cookie 'my_unique_id' not found in fromdb.php");
    exit;
}

//retrieving data from db where UniqueId is equal to this page's UniqueId
$sql="SELECT * FROM duka WHERE UniqueId = '$unique_id';";

$result = mysqli_query($conn, $sql);
$resultCheck=mysqli_num_rows($result);

if ($resultCheck > 0) {

    while ($row = mysqli_fetch_assoc($result)) {
        $data = $row["CheckoutReqID"];
    }
}
//value to be printed using console.log following an ajax get method
echo json_encode($data);
?>

注意事项

  • Cookie的安全性: Cookie存储在客户端,容易被篡改。因此,不要在Cookie中存储敏感信息。
  • Cookie的有效期: 根据实际需求设置Cookie的有效期。
  • Cookie的路径: 设置Cookie的路径,确保只有需要的页面可以访问该Cookie。
  • 错误处理: 确保在response.php和fromdb.php中处理Cookie不存在的情况。

总结

通过使用Cookie替代Session,可以有效地解决回调URL页面Session ID变更的问题,从而保证请求与回调数据的正确关联。在实际应用中,需要注意Cookie的安全性、有效期和路径,并进行充分的错误处理。这种方法提供了一种简单而有效的解决方案,适用于需要在回调URL中保持ID一致性的场景。

        
      
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。