views:

869

answers:

3

All,

Sorry - this is probably a very strange question.

I'm working on a Flash RIA. One of the things it does is call an ASP page (that resides on another domain) to retrieve some data.

However, that ASP page requires users to log-in to that site before they're allowed to call that ASP page.

So, my first attempt at getting this to work in the Flash app was to use loadVars.sendAndLoad() to post the login variables to the login page. This sets the cookies/session variables to establish my "logged-in" status. Then, later, when the Flash app calls the ASP page to request the data it needs, everything works. In other words, the loadVars.sendAndLoad call to the first page logs me in, and that log-in status is maintained (somehow), so that when the Flash app calls the ASP page later, the ASP page believes I'm still logged in.

A fine solution all around, except now the Flash application will be deployed on another domain. In other words, the ASP page (and the login page) are on domainA.com, but the Flash application will be on domainB.com. And Flash apps can't call URLs on different domains (I know about crossdomain policy files, but for a variety of reasons, that isn't an option).

So, my next thought was this - set up a PHP page on domainB.com that uses cURL to pass the login variables to the login page. Set up another PHP page on domainB.com that uses cURL to call the ASP page.

Then, I can set my Flash app to call those PHP pages which will act as "proxies".

However, this doesn't work. When I call the first PHP page (which passes variables to the login page on domainA.com), I think THAT works. However, if I then call the second PHP page, the ASP page on domainA.com rejects the request, as though I'm not logged in.

In other words, when I run everything out of Flash - it seems like the "logged-in" status is maintained from the first request to subsequent requests. However, when I run everything from the PHP pages, the logged in state isn't maintained.

The first PHP page seems to log me into the system. But the second PHP page isn't credited with being logged in.

Any idea how the cookies are handled differently in Flash and PHP that would explain this difference?

I'm happy to provide much more detail, based on any advice or guidance.

Many thanks in advance!

---- EDIT ----

Based on the terrific feedback and suggestions, I've gotten this to work. I haven't had a chance to polish it; it may be that some of the cURL options are unnecessary or redundant. But at least, it works. Here's the code:

<?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);

?>

Needless to say, there may be much better ways to accomplish this, or some serious issues with my code. But working is, for now, better than nothing. I'd never have gotten this to work without the help of the community, and the people below. Many, many thanks!

+1  A: 

Can you paste the problem script?

At first glance i would check that the cookie is being caught and passed onto the second script (caught from curl response and passed into curl for the second request), curl doesn't automatically handle cookies (i don't think), you have to play the part of the web browser, saving the response header (containing the cookie).

I think you script should look like:

<?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;


?>

this is presuming that you dont mind the header guff comming back in the first request.

Good Luck

Question Mark
Dougle - Many thanks for your response! I've added the script, if you have a chance to take a second look.
mattstuehler
+1  A: 

The login state is most likely maintained using cookies. When you proxy through PHP, it isn’t going to store the cookies between requests. While there are baroque ways to work around this (perhaps you could pass the cookie back to Flash), this doesn’t sound like a scalable or durable solution. Is there no way to use a cross-domain policy or some other way of having Flash directly contact the site you’re logging in to (like a JSON callback)?

Nate
Nate - that's a great point. I'm thinking about combining the two PHP scripts into one, so I don't need to maintain the login state. So, the first half of the script calls the login page; the second page calls the data-providing ASP page. Even still, the login state is not maintained. It sounds like I need to keep track of the cookies, and make sure both cURL posts use them. I'm not sure how to do that - any advice? Many thanks!
mattstuehler
[Here](http://coderscult.com/php/php-curl/2008/05/20/php-curl-cookies-example/) is an example of how to use cookies with PHP’s cURL module. You can both store incoming cookies and send them with your next request. You need to associate the cookies with your Flash application’s session—by storing each Flash session’s cookies separately—so that two Flash sessions don’t share a login, which would be a security problem. One way to do this would be to store the temporary cookie jar filename in PHP’s $_SESSION variable.
Nate
But again, I’d only look at this as a last resort. Any “non proxy” solution is going to be preferable.
Nate
+1  A: 

PHP does not handle cookies for you as auto-magically as flash does. You must pass to the function that does the post, a bag of options including a path to the file to stuff cookies in.

A description of how to make that bag of options can be found here: http://usphp.com/manual/en/http.request.options.php

Joe Langeway
Excuse me, you must pass the path to the file in which to stuff cookies to both the call that logs you in and the call that uses that login to do whatever else.
Joe Langeway
Joe - it sounds like you've identified the problem. As others have suggested, I've combined the two PHP scripts into one, so I don't need to maintain the login state between them. So, the first half of the script calls the login page; the second page calls the data-providing ASP page. Now - I just need to figure out how to keep track of the cookies, and make sure both cURL posts use them. I'm not sure how to do that - any advice? Many thanks!
mattstuehler
Matt, sorry the link I pasted assumed you were using a subset of php that you apparently were not. I'm glad you got your answer it looks like.
Joe Langeway