【问题标题】:How to Handle API with Session (XML 307 Response) in PHP如何在 PHP 中使用 Session(XML 307 响应)处理 API
【发布时间】:2019-03-05 08:06:58
【问题描述】:

我这里有情况。目前我开发了一个web,需要做一个函数来与设备API进行通信。现在我被307(临时重定向)困住了。

所以,流程是,首先我需要使用登录功能进行会话。如果登录成功会给出响应307 (Temporary Redirect),并且响应头(sessionId)中有Location。因此,要发布另一个请求,我们需要遵循位置 (sessionId)。当我在 Postman 中尝试登录功能始终成功以获取位置(SessionId)时,但从这些位置发布另一个请求有时成功,有时不成功。我尝试在 PHP 中创建它,因为登录总是成功并获得位置,但是当发布另一个请求时它总是失败。

这是用于登录的 XML 函数:

 POST / HTTP/1.1
 Host: 111.222.123.123:8001
 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:lgi="http://www.qwerty.org/func/LGI">
     <soapenv:Header/>
     <soapenv:Body>
         <lgi:LGI>
             <lgi:OPNAME>username</lgi:OPNAME>
             <lgi:PWD>password</lgi:PWD>
         </lgi:LGI>
     </soapenv:Body>
 </soapenv:Envelope>

这是来自登录功能的标头响应:

HTTP/1.1 307 Temporary Redirect
Location: http://111.222.123.123:8001/00112233
Server: Qwerty web server
Content-Type: text/xml; charset="utf-8"
Content-Length: 411

00112233 是 POST 另一个请求的位置 (SessionId)。但同样,如果来自 Postman,有时成功,有时不成功。如果从 PHP 获取位置 (SessionId) 后总是无法 POST 请求

这是我的 Login 功能的 PHP 脚本:

    $soapUrl = "http://111.222.123.123:8001/";

    $xml_post_string1 = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:lgi="http://www.qwerty.org/func/LGI">
                            <soapenv:Header/>
                            <soapenv:Body>
                                <lgi:LGI>
                                    <lgi:OPNAME>username</lgi:OPNAME>
                                    <lgi:PWD>password</lgi:PWD>
                                </lgi:LGI>
                            </soapenv:Body>
                        </soapenv:Envelope>';

    $headers1 = array(
                    "Content-type: text/xml;charset=\"utf-8\"",
                    "Accept: text/xml",
                    "Cache-Control: no-cache",
                    "Pragma: no-cache",
                    "SOAPAction: http://www.qwerty.org/func/LGI", 
                    "Content-length: ".strlen($xml_post_string1),
                );

        $url = $soapUrl;

        $ch1 = curl_init();
        curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, 1);
        curl_setopt($ch1, CURLOPT_URL, $url);
        curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch1, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
        curl_setopt($ch1, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch1, CURLOPT_POST, true);
        curl_setopt($ch1, CURLOPT_POSTFIELDS, $xml_post_string1);
        curl_setopt($ch1, CURLOPT_HTTPHEADER, $headers1);

        curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch1, CURLOPT_VERBOSE, 1);
        curl_setopt($ch1, CURLOPT_HEADER, 1);

        $response1 = curl_exec($ch1); 

        $header_size = curl_getinfo($ch1, CURLINFO_HEADER_SIZE);
        $header = substr($response1, 0, $header_size);

        $break1= explode('/', $header);
        $break2= preg_split('/[\s]+/', $break1[4]);
        $sessionId = $break2[0];

这是我在获得 Location / SessionId 后提出的要求

    $soapUrlToken1 = "http://111.222.123.123:8001/";
    $soapUrlToken2 = $soapUrlToken1.$sessionId ;

    $xml_post_string2 = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sh="http://www.qwerty.org/func/SH_SUB">
                           <soapenv:Header/>
                           <soapenv:Body>
                              <sh:SH_SUB>
                                 <sh:USER>USERNAME</sh:USER>
                                 <sh:DETAIL>TRUE</sh:DETAIL>
                              </sh:SH_SUB>
                           </soapenv:Body>
                        </soapenv:Envelope>';

    $headers2 = array(
                    "POST /$token HTTP/1.1",
                    "Host: 111.222.123.123:8001",
                    "Content-type: text/xml;charset=\"utf-8\"",
                    "Accept: text/xml",
                    "Accept-Encoding: gzip,deflate",
                    "User-Agent: City Commons-HttpClient/3.1",
                    "SOAPAction: http://www.qwerty.org/func/SH_SUB",

                    "Content-length: ".strlen($xml_post_string2),
                );

    $urlToken = $soapUrlToken2;
    //echo "<br />".$urlToken."<br />";

    $ch2 = curl_init();
    curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, 1);
    curl_setopt($ch2, CURLOPT_URL, $urlToken);
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch2, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    curl_setopt($ch2, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch2, CURLOPT_POST, true);
    curl_setopt($ch2, CURLOPT_POSTFIELDS, $xml_post_string2);
    curl_setopt($ch2, CURLOPT_HTTPHEADER, $headers2);

    $response2 = curl_exec($ch2); 

    $response3 = str_replace("<SOAP-ENV:Body>","",$response2);
    $response4 = str_replace("</SOAP-ENV:Body>","",$response3);
    $parser2 = simplexml_load_string($response4);

在 php 中,关于 sessionId 的响应总是无效或超时。我已经问过 API 团队,他们只解释了登录后必须保持会话和端口才能发出另一个请求

那么在 PHP 中处理 307(临时重定向) 的最佳解决方案是什么?

谢谢

【问题讨论】:

    标签: php xml api soap


    【解决方案1】:

    已经找到解决方案。获得位置(SessionId)后,我不需要再次使用curl_init()curl_init()初始化一个新会话,这就是问题所在,之前已经获得的位置 (sessionId) 将被 curl_init() 销毁

    【讨论】:

      猜你喜欢
      • 2015-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      相关资源
      最近更新 更多