Skip to content

Instantly share code, notes, and snippets.

@mintindeed
Created July 28, 2013 04:35
Show Gist options
  • Save mintindeed/6097418 to your computer and use it in GitHub Desktop.
Save mintindeed/6097418 to your computer and use it in GitHub Desktop.
This is a very simple API authentication method. It doesn't do any kind of flood protection, for example. In general an OAuth implementation would be better.
<?php
$server_url = 'http://example.com/endpoint/?ts=' . time();
$shared_secret = 'random string of text'; // This is the same in server and client
$public_key = 'hello world'; // Each client has its own allowed key, this key is the same in the server and client
$headers = array(
'x-pmc-key: ' . $public_key,
'x-pmc-signature: ' . md5( $public_key . $shared_secret ),
);
// Client makes the request
$ch = curl_init( $server_url );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_FRESH_CONNECT, true );
curl_setopt( $ch, CURLOPT_HEADER, true );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 60 );
curl_setopt( $ch, CURLOPT_TIMEOUT, 59 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_MAXREDIRS, 5 );
$data = curl_exec( $ch );
var_dump($data);
die();
<?php
$shared_secret = 'random string of text'; // This is the same in server and client
$allowed_keys = array(
'hello world', // Each client has its own allowed key, this key is the same in the server and client
);
/*
Pass the key and signature through headers. Headers get encrypted via SSL, but querystrings do not. This makes the key and
signature slightly harder to detect by a 3rd party. The server will need to handle caching. If there's a proxy cache in front
of the request, then the client should pass a unique querystring value (this won't be read by the server, its purpose is just
to bypass the proxy cache).
*/
$public_key = ( isset($_SERVER['HTTP_X_PMC_KEY']) ) ? $_SERVER['HTTP_X_PMC_KEY'] : '';
$signature = ( isset($_SERVER['HTTP_X_PMC_SIGNATURE']) ) ? $_SERVER['HTTP_X_PMC_SIGNATURE'] : '';
// See if the request signature matches our signature
$allowed_keys_id = array_search( $public_key, $allowed_keys );
if ( ( false === $allowed_keys_id ) || ( $signature !== md5( $allowed_keys[$allowed_keys_id] . $shared_secret ) ) ) {
// Return a forbidden header and no content.
header( 'HTTP/1.0 403 Forbidden' );
die();
}
// Return an OK header. Add Content-Type and other headers as needed. Return API response data.
header( 'HTTP/1.0 200 OK' );
echo 'match';
die();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment