Hi All,
I managed to find a solution as detailed for other’s with a similar issue. Please see below. Any references to SWFUpload can be substituted for Uploadify.
The original hook fails due to the SWFUpload not passing the session cookies in it’s request so WordPress thinks it’s a non-logged-in user.
So what I did was pass $_COOKIE[AUTH_COOKIE]
and $_COOKIE[LOGGED_IN_COOKIE]
values to the page from which SWFUpload is initialised whereby one can then add the additional parameters in a similar fasion as this:-
'formData' : {'action': 'uploadClientFiles', 'auth_cookie': auth_cookie, 'logged_in_cookie': logged_in_cookie}
Whilst this is not terribly secure as you are in essence then sending the session variables over the wire as-is and potentially allowing someone to sniff out the session details therefore I also added an encryption/decryption method on either side of the requests. These two functions were found at https://www.php.net/manual/en/function.mcrypt-encrypt.php#71452 courtesy of davidwhthomas.
So the methodology is as follows.
1. Encrypt the cookies to send to javascript variables for SWFUpload to POST back with its request.
2. Decrypt the POSTed back variables.
One last point to mention is that to make it harder for anyone to “spoof” the application by sniffing the cookie variables passed in the POST, I have made the “key” of the encryption use the users IP address so that only one IP address is valid and can decrypt correctly.
The functions slightly amended to allow IP_address as the key:-
function encryptCookie($value){
if(!$value){return false;}
$key = $SERVER[REMOTE_ADDR];
$text = $value;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
return trim(base64_encode($crypttext)); //encode for cookie
}
function decryptCookie($value){
if(!$value){return false;}
$key = $SERVER[REMOTE_ADDR];
$crypttext = base64_decode($value); //decode cookie
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv);
return trim($decrypttext);
}
The original hook:-
add_action('wp_ajax_uploadClientFiles', 'uploadClientFiles');
Also needs to have a _nopriv alternative which we pass to a new function to re-initialize the session with POST values which can be added to a SWFUpload request as below:-
add_action('wp_ajax_nopriv_uploadClientFiles', 'reSession');
Here I took the top lines from the wp-admin/async-load.php file but amended them to decrypt the cookies as per the function mentioned above with the IP_Address as the key. Then when the authorization was concluded I added a call to the original function I had been hoping to reach as indicated by the add_action('wp_ajax_uploadClientFiles', 'uploadClientFiles');
call.
Be sure to die() here as otherwise you will still get the -1 output from the original call to admin-ajax.php after line 46 – do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );
has been executed.
Here is the reSession function:-
function reSession(){
define('WP_ADMIN', true);
if ( defined('ABSPATH') )
require_once(ABSPATH . 'wp-load.php');
else
require_once('../wp-load.php');
// Flash often fails to send cookies with the POST or upload, so we need to pass it in GET or POST instead
if ( is_ssl() && empty($_COOKIE[SECURE_AUTH_COOKIE]) && !empty($_REQUEST['auth_cookie']) )
$_COOKIE[SECURE_AUTH_COOKIE] = decryptCookie($_REQUEST['auth_cookie']);
elseif ( empty($_COOKIE[AUTH_COOKIE]) && !empty($_REQUEST['auth_cookie']) )
$_COOKIE[AUTH_COOKIE] = decryptCookie($_REQUEST['auth_cookie']);
echo decryptCookie($_REQUEST['auth_cookie']);
if ( empty($_COOKIE[LOGGED_IN_COOKIE]) && !empty($_REQUEST['logged_in_cookie']) )
$_COOKIE[LOGGED_IN_COOKIE] = decryptCookie($_REQUEST['logged_in_cookie']);
unset($current_user);
require_once('./admin.php');
uploadClientFiles();
die();
}
and finally for completeness the setting of the cookies as javascript variables to be included in the page where SWFUpload is to be called/used.
wp_localize_script('some-script', 'auth_cookie', encryptCookie($_COOKIE[AUTH_COOKIE]));
wp_localize_script('some-script', 'logged_in_cookie', encryptCookie($_COOKIE[LOGGED_IN_COOKIE]));
I hope this helps someone in the future with similar predicament(s)!
Thanks,
Rob.