2009-08-10 43 views
1

全部,在PHP中,来自cURL的POST请求如何/不像来自Flash中loadVars的POST请求?

对不起 - 这可能是一个很奇怪的问题。

我正在使用Flash RIA。它所做的一件事就是调用一个ASP页面(驻留在另一个域中)来检索一些数据。

但是,该ASP页面要求用户在允许调用该ASP页面之前登录该网站。

因此,我第一次尝试在Flash应用程序中使用它,是使用loadVars.sendAndLoad()将登录变量发布到登录页面。这将设置cookies/session变量来建立我的“登录”状态。然后,稍后,当Flash应用程序调用ASP页面来请求所需的数据时,一切正常。换句话说,对第一页的loadVars.sendAndLoad调用使我登录,并且以某种方式维护了登录状态,以便稍后Flash应用程序调用ASP页时,ASP页认为我仍然记录in。

一个很好的解决方案,除了现在Flash应用程序将部署在另一个域中。换句话说,ASP页面(和登录页面)位于domainA.com上,但Flash应用程序将位于domainB.com上。并且Flash应用程序不能调用不同域的URL(我知道跨域策略文件,但出于各种原因,这不是一种选择)。

所以,我的下一个想法是 - 在domainB.com上设置一个PHP页面,它使用cURL将登录变量传递到登录页面。在domainB.com上设置另一个使用cURL调用ASP页面的PHP页面。

然后,我可以设置我的Flash应用程序来调用那些充当“代理”的PHP页面。

但是,这不起作用。当我调用第一个PHP页面(它将变量传递到domainA.com上的登录页面)时,我认为这是有效的。但是,如果我然后调用第二个PHP页面,则domainA.com上的ASP页面会拒绝该请求,就好像我没有登录。

换句话说,当我将所有内容都运行在Flash之外 - 看起来像“登录”状态从第一个请求维持到后续请求。但是,当我运行PHP页面中的所有内容时,登录状态不会被保留。

第一个PHP页面似乎将我登录到系统中。但第二个PHP页面没有记入登录。

任何想法如何在Flash和PHP中处理不同的cookie来解释这种差异?

根据任何建议或指导,我很乐意提供更多的细节。

非常感谢提前!

---- ----编辑

基于了不起的意见和建议,我已经得到了这个工作。我没有机会擦亮它;可能有些卷曲选项是不必要的或多余的。但至少,它的工作。下面的代码:

<?php 

    $ckfile = tempnam (".", "CURLCOOKIE"); 

    $url_1 = 'https://somedomain.com/loginService'; 
    $url_2 = 'https://somedomain.com/getMyData.asp'; 

    $fields_1 = array(
     'field1'=>"blah", 
     'field2'=>"blah", 
     'field3'=>"blah", 
    ); 

    $fields_2 = array(
     'fieldX'=>"blah", 
     'fieldY'=>"blah", 
     'fieldZ'=>"blah", 
    ); 


    $a=''; 
    $postvars_1 = ''; 
    foreach($fields_1 as $key=>$value) { 
     $postvars_1.= $a.urlencode($key).'='.urlencode($value); 
     $a='&'; 
    } 

    $a=''; 
    $postvars_2 = ''; 
    foreach($fields_2 as $key=>$value) { 
     $postvars_2.= $a.urlencode($key).'='.urlencode($value); 
     $a='&'; 
    } 

    $ch = curl_init(); 

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
    curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE); 
    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile); 
    curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile); 
    curl_setopt($ch, CURLOPT_COOKIE, session_name() . '=' . session_id()); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);  
    curl_setopt($ch, CURLOPT_POST, count($fields)); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars); 

    curl_setopt($ch, CURLOPT_URL, $url_1); 
    curl_setopt($ch, CURLOPT_POST, count($fields_1)); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars_1); 
    $result_1 = curl_exec($ch); 

    curl_setopt($ch, CURLOPT_URL, $url_2); 
    curl_setopt($ch, CURLOPT_POST, count($fields_2)); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars_2); 
    $result_2 = curl_exec($ch); 

    curl_close($ch); 

    header("Content-type: text/xml"); 
    print $result_2; 

    unlink($ckfile); 

?> 

不用说,有可能是更好的方式来做到这一点,或者我的代码一些严重的问题。但现在工作总比没有好。没有社区和下面的人的帮助,我永远都不会得到这个工作。非常感谢!

回答

1

您可以粘贴问题脚本吗?乍看之下,我会检查cookie是否被捕获并传递到第二个脚本(从curl响应中捕获并传递给第二个请求的curl),curl不会自动处理cookie(我不认为),您必须播放Web浏览器的一部分,保存响应标头(包含cookie)。

我想你的脚本应该是这样的:

<?php 

    // first request 

    $url = 'https://somedomain.com/login/'; 

    $fields = array(
     'field1'=>"aaaaa", 
     'field2'=>"bbbbb", 
     'field3'=>"ccccc" 
    ); 

    $postvars = array(); 
    foreach($fields as $key=>$value) { 
     $postvars[] = urlencode($key).'='.urlencode($value); 
    } 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_POST, count($fields)); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&',$postvars)); 
    curl_setopt($ch, CURLOPT_HEADER, 1); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    $result = curl_exec($ch); 
    preg_match('/^Set-Cookie: (.*?);/m', $result, $auth_value); 
    curl_close($ch); 

    // second request 

    $url = 'https://somedomain.com/getMyData.asp'; 
    $fields = array(
     'fieldX'=>"xxxx", 
     'fieldY'=>"yyyy", 
     'fieldZ'=>"zzzz" 
    ); 

    $postvars = array(); 
    foreach($fields as $key=>$value) { 
     $postvars[] = urlencode($key).'='.urlencode($value); 
    } 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_POST, count($fields)); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&',$postvars)); 
    curl_setopt($ch, CURLOPT_COOKIE, 'authenticate='.urlencode($auth_value[1])); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    $result = curl_exec($ch); 
    curl_close($ch); 

    print $result; 


?> 

,这是假设你不介意的头废话中的第一个请求回正在添加。

好运

+0

Dougle - 非常感谢您的回应!如果您有机会再次观看,我已经添加了脚本。 – mattstuehler 2009-08-10 18:48:52

1

登录状态使用Cookie最有可能维持。当您通过PHP进行代理时,它不会在请求之间存储Cookie。虽然有巴洛克式的方法来解决这个问题(也许你可以将cookie传递回Flash),但这听起来不像一个可扩展或持久的解决方案。是否没有办法使用跨域策略或其他方式让Flash直接联系您登录的网站(如JSON回调)?

+0

Nate - 这是一个很好的观点。我正在考虑将两个PHP脚本合并为一个,所以我不需要保持登录状态。所以,脚本的前半部分调用登录页面;第二页调用提供数据的ASP页面。即使如此,登录状态不会被维护。这听起来像我需要跟踪cookie,并确保两个cURL帖子使用它们。我不知道该怎么做 - 有什么建议吗?非常感谢! – mattstuehler 2009-08-10 18:51:19

+1

[这里](http://coderscult.com/php/php-curl/2008/05/20/php-curl-cookies-example/)是一个如何在PHP的cURL模块中使用cookie的例子。您既可以存储传入的Cookie,也可以将您的下一个请求发送给他们。您需要将Cookie与Flash应用程序的会话关联起来(通过分别存储每个Flash会话的Cookie),以便两个Flash会话不共享登录信息,这将是一个安全问题。一种方法是将临时cookie jar文件名存储在PHP的$ _SESSION变量中。 – Nate 2009-08-10 19:24:24

+0

但是,我只是把这看作是最后的手段。任何“非代理”解决方案都将是可取的。 – Nate 2009-08-10 19:25:13

1

PHP不像Flash那样为您自动处理cookie。你必须传递到执行后,选项包括对文件的东西饼干的路径的袋子功能

如何使的选项包的描述可以在这里找到:http://usphp.com/manual/en/http.request.options.php

+0

对不起,您必须将文件路径传递给将您登录的呼叫以及使用该登录名称的呼叫进行其他操作。 – 2009-08-10 18:41:28

+0

乔 - 这听起来像你已经确定了问题。正如其他人所建议的,我将两个PHP脚本合并为一个,因此我不需要维护它们之间的登录状态。所以,脚本的前半部分调用登录页面;第二页调用提供数据的ASP页面。现在 - 我只需要弄清楚如何跟踪cookie,并确保两个cURL帖子都使用它们。我不知道该怎么做 - 有什么建议吗?非常感谢! – mattstuehler 2009-08-10 18:52:51

+0

马特,对不起,我粘贴的链接假设你使用的PHP的一个子集,你显然不是。我很高兴你的答案看起来像。 – 2009-08-10 23:10:54