Send XML files modified with AS3 to password protected PHP-file and save them

Now that was one ride… took the whole night figuring it out, and so I will share it, of course. :D

I coded some flex-apps in the past, and I’m still working on it. Normally I use simple XML files to store configuration data, as they are so wonderfully easy to read with AS3.

But till now, changing these options meant opening on the local computer and editing them, or writing some (PHP4) compatible code with PHP, that was far from being readable.

So I decided to design a simple flash-configuration gui (only basic stuff here), but to prevent “funny people” from opening it and changing the options all the time, it had to come with some user-authentication system.

This part wasn’t that hard either, there are tons of tutorials out there how you can send (even MD5 protected) login data to a server side script like php, so I skip that.

But, and that wasn’t easy (at least for me), how to send the XML-data AND the login data together so a PHP-file can handle it.

Basically you do the following.

  1. Put the username/password/any other parameter directly into the URL you open and catch the with PHP’s $_GET[”…”] command
  2. Put the updated XML into the raw data post object, you can access via file_get_contents(”php://input”);

1. Login form with Flex/AS3

This is the first part. You have to collect username/password before doing anything else. Create some login form

<mx:Form id=“login_form”>
   <mx:FormItem label=“Username”>
	<mx:TextInput id=“username”/>
   </mx:FormItem>
   <mx:FormItem label=“password”>
         <mx:TextInput id=“password” displayAsPassword=“true”/>
   </mx:FormItem>
   <mx:FormItem>
	<mx:Button label=“submit” id=“submit_login” click=“login_user.send();”/>
   </mx:FormItem>
</mx:Form>

and a corresponding HTTPService

<mx:HTTPService
	id=“login_user”
	result=“checkLogin(event)”
	method=“POST”
	url=“any.php”
	useProxy=“false”>
		<mx:request xmlns=“”>
			<username>{MD5.hash(username.text)}</username>
			<password>{MD5.hash(password.text)}</password>
		</mx:request>
</mx:HTTPService>

This Service (login_user) opens any.php and sends the under <mx:request>… defined parameters (username,password) to it. The parameters are encrypted, visible passwords are something I don’t like that much ;). Visit the as3corelib  site to use these functions.

The any.php is straightforward than.

Define a user and password (this example is for one user without any fancy MySQL connection or anything)

$user = "admin";
$pass = "admin";
and than check the passed variables (from flex) for their correctness. 
if (isset($_POST["username"]) && isset($_POST["password"]) && $_POST["saveXML"]!="yes")
{
	$output = "<loginsuccess>“;
	if($_POST[”username”]==md5($user) && $_POST[”password”]==md5($pass))
		{
			$output .= “yes”;
		}else{
			$output .= “no”;
		}
	$output .= “</loginsuccess>“;
//output all the XML
print ($output);
}

If the submitted login data is correct, <loginsuccess>yes</loginsuccess>  will be returned. Otherwise it’s <loginsuccess>no</loginsuccess>.
If any.php finished, the Flex HTTPService calls the checkLogin function. It checks if the login data was correct and you can do what you want ;)

private function checkLogin(evt:ResultEvent):void
{
	if(evt.result.loginsuccess == “yes“)
	{
	//do something
	}
	if(evt.result.loginsuccess == “no“)
	{
	mx.controls.Alert.show(”Invalid username/password“);
	}
}

 

2. Send XML and credentials to PHP

So now you have a login form, checking if you are allowed to do something with a php-script. But what if you have to save something into a file (Flex/AS3 can’t do this), you’ll have to pass the new content to a server side script like php and let it do the work.

If, at this part, no credential-checking takes place, anyone knowing this script can use it so we have to combine send the XML-content via POST and the credentials via GET to php.

First, you need a HTTPService again

<mx:HTTPService
	id=“save_xml”
	result=“submitXML(event)”
	contentType=“application/xml”
	method=“POST”
	url=“any.php”
	useProxy=“false”>
</mx:HTTPService>

It’s important to define the content type (application/xml) here, and add NO <mx:request> to the HTTPService. Instead the url of save_xml is defined dynamically inside the AS3 code, when you want to save the xml to a file.

save_xml.url = "maximeeLite.php?password=“+MD5.hash(password.text)
               +”&username=“+MD5.hash(username.text)
               +”&saveXML=yes“;
save_xml.send(newXML);

As you see, password and username are passed as parameters within the url, the save_xml.send(newXML) passes the XML-Object newXML to any.php.

All you have to do now is some PHP again.

elseif ($_GET["saveXML"]=="yes")
{
	$output = "<savesuccess>“;
	if($_GET[”username”]==md5($mmConfig_user) && $_GET[”password”]==md5($mmConfig_pass))
	{
		$xml = file_get_contents(”php://input”);
	    	$file = fopen(”your.xml”,”wb”);
    		fwrite($file, $xml);
	    	fclose($file);
		$output .= “yes”;
	}
	else
	{
		$output .= “no”;
	}
	$output .= “</savesuccess>“;
//output all the XML
print ($output);
}

Check 1. if saveXML is yes (otherwise no XML-storing is wanted), than 2. check username/password and 3. get the new XML content with

$xml = file_get_contents("php://input"); 

and write it to the file (your.xml).

As with the login-script, here a <savesuccess>-field is returned, and can be checked by AS3 than.

private function submitXML(evt:ResultEvent):void
{
	if(evt.result.savesuccess == “yes“)
	{
	//file saved successfully
	}
	if(evt.result.savesuccess == “no“)
	{
	//file not saved
	}
}

 

That’s it. Perhaps I helped you somehow…

 

Tags: , , , ,


 
 
 

Leave a Reply


  • Stats

    Besucher online: 1
    Besucher heute: 8
    Besucher seit 29. März 2008: 6358
    39 Besucher haben sich diese Seite angesehen
  • Spam Blocked