PHP async request with auth

InĀ http://stackoverflow.com/questions/962915/how-do-i-make-an-asynchronous-get-request-in-php, it shows how to send asynchronous request from PHP script, so that the webpage is immediately rendered without waiting the request to finish.

This technique is important if you want to implement background processing in web app, just by send a request to own script that going to run the process at background, while the main script continue to run and produce the webpage.

However, the request made to the background process page maybe can be accessed directly, just by entering the correct URL to browser, and you want to make sure this page is not being abused by users.

During sending the request, we can modify the request header as an authentication method to check if request is originally come from our own web application. You may modify user agent header and set it as your own webapp UA

‘User-Agent: my-web-app’, and in your script, check the value of $_SERVER[‘HTTP_USER_AGENT’]

Or, for more security, use custom header name, as follows:

$host = 'localhost';
$path = '/bg.php';
$qs = array(); // query string
if (!empty($qs)) {
    $qs = http_build_query($qs);
    $path = $path .'?'. $qs;
}
$fp = fsockopen($host, 80, $errno, $errdesc);
if ($fp) {
    $req  = "GET $path HTTP/1.0\r\n";
    $req .= "Host: $host\r\n";
    $req .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $req .= "Content-Length: ". strlen($qs) ."\r\n";
    $req .= "Anxx0Wjoiw3: asmkd3A0das2wq2\r\n";
    $req .= "Connection: Closern\r\n";
    fputs($fp, $req);
    fclose($fp);
}

And in the background process script, check if the custom header is correct:

if (isset($_SERVER['HTTP_ANXX0WJOIW3']) && $_SERVER['HTTP_ANXX0WJOIW3'] == 'asmkd3A0das2wq2') {
    // do background process
}

Note: Custom header (or other headers), can be access using $_SERVER variables, with the key prepended with ‘HTTP_’

As an addition, use encrypted value for the header name and value, and also change the value for every several hour by autogenerate it using mktime() and strtotime(), provided you secure the encrypted string with salt data, example:

$salt = 'secret-key';
$hash = md5($salt . mktime(date('H', strtotime('+6 hour')), 0, 0));

Cloudflare & phpBB3

Session handling in phpBB3 requires a user to use one IP address per session, therefore if your IP address changed, you will be prompt to login again.

Cloudflare is a web caching service that cache static contents of a website by acting as the nameserver that manage the website domain name. Therefore, every request to the domain name will pass through Cloudflare system first and any cached contents will be served from Cloudflare servers instead of the web hosting server.

However, when using Cloudflare service, the REMOTE_ADDR value for PHP $_SERVER will follow Cloudflare servers IP address. Therefore, you might face problem when using phpBB (or any other web app that rely on session tied to the IP address) with this service.

So, we need to edit phpBB session.php file to grab the correct variable for the users’ real IP address. Edit includes/session.php

Find:

$this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : '';

Replace with:

$this->ip = (!empty($_SERVER['HTTP_CF_CONNECTING_IP']))
          ? (string) $_SERVER['HTTP_CF_CONNECTING_IP']
          : ((!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : '');

HTTP_CF_CONNECTING_IP is special header value passed by Cloudflare servers containing visitors’ real IP address, and in case this variable not set, we use the good ol REMOTE_ADDR