Created
February 5, 2013 05:48
-
-
Save CNG/4712514 to your computer and use it in GitHub Desktop.
First whack at a single PHP file to both generate random keys and check if they are expired, while updating the expiration date every time they are checked. This allows generating a key and making it expire if unused too long.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
USAGE: | |
To request a new token: ?newtoken=please | |
To ask if token is valid: ?token=xamBVbmRlKcSSVsrxt8WEqQ6NdpS7z | |
SETUP: | |
$tokensFilename must be writable by script, preferably in a location outside | |
the web root | |
DEVELOPMENT NOTES: | |
This set of functions could be more streamlined. Part of this is due to | |
changing the token strategy midway, but it works as is, so in the interest | |
of not spending more time refactoring and testing, I'll leave it. | |
*/ | |
// Filename where tokens are stored | |
$tokensFilename = 'tokens.txt'; | |
// Maximum token age in seconds | |
$maxAge = 3600; | |
// Received token for validating | |
$token = isset($_REQUEST['token']) ? preg_replace('/[^-_a-zA-Z0-9]/', '', $_REQUEST['token']) : FALSE; | |
// Requesting new token | |
$needNewToken = isset($_REQUEST['newtoken']) && !strcmp($_REQUEST['newtoken'],'please'); | |
/* | |
* Given optional string length | |
* Returns random string | |
*/ | |
function randomString($length = 30) { | |
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-'; | |
$randomString = ''; | |
for ($i = 0; $i < $length; $i++) { | |
$randomString .= $characters[rand(0, strlen($characters) - 1)]; | |
} | |
return $randomString; | |
} | |
/* | |
* Given filename where tokens stored | |
* Returns array with tokens as keys and timestamps as values | |
*/ | |
function getAllTokens($filename){ | |
$rawcontents = explode("\n",file_get_contents($filename)); | |
foreach ($rawcontents as $key => $value){ | |
if (strlen($value) < 10){ | |
unset($rawcontents[$key]); | |
} | |
} | |
$contents = array(); | |
foreach($rawcontents as $line){ | |
list($token, $timestamp) = explode("|",$line); | |
$contents[$token] = $timestamp; | |
} | |
unset($line); | |
return $contents; | |
} | |
/* | |
* Given array with tokens as keys and timestamps as values and filename | |
* Returns true on successful file write | |
*/ | |
function setAllTokens($filename, $tokenInfo){ | |
$contents = ''; | |
foreach($tokenInfo as $token => $timestamp){ | |
$contents .= "$token|$timestamp\n"; | |
} | |
unset($token,$timestamp); | |
return file_put_contents($filename,$contents); | |
} | |
/* | |
* Given array with tokens as keys and timestamps as values and expiration duration in seconds | |
* Returns same array with expired tokens removed | |
*/ | |
function validTokens($tokenInfo, $maxAge){ | |
foreach($tokenInfo as $token => $timestamp){ | |
if( time() - intval($timestamp) > $maxAge ){ | |
unset($tokenInfo[$token]); | |
} | |
} | |
unset($token,$timestamp); | |
return $tokenInfo; | |
} | |
/* | |
* Given filename where tokens stored | |
* Returns new token after adding it to token list with timestamp | |
*/ | |
function newToken($filename){ | |
$token = randomString(30); | |
$timestamp = time(); | |
$contents = file_get_contents($filename); | |
$contents .= "$token|$timestamp\n"; | |
file_put_contents($filename,$contents); | |
return $token; | |
} | |
/* | |
* Given filename where tokens stored and token to search for | |
* Returns TRUE after timestamp successfully updated for token | |
*/ | |
function renewToken($filename,$token){ | |
$timestamp = time(); | |
$tokens = getAllTokens($filename); | |
$tokens[$token] = $timestamp; | |
setAllTokens($filename,$tokens); | |
return TRUE; | |
} | |
/* | |
* Given filename where tokens stored and max token age in seconds | |
* Returns TRUE after removing expired tokens from file | |
*/ | |
function cleanTokens($filename,$seconds){ | |
$tokens = getAllTokens($filename); | |
setAllTokens($filename,validTokens($tokens,$seconds)); | |
return TRUE; | |
} | |
/* | |
* Given filename where tokens stored, token to search for and max token age in seconds | |
* Returns TRUE if token is expired or FALSE otherwise | |
*/ | |
function isTokenValid($filename,$token,$seconds){ | |
cleanTokens($filename,$seconds); | |
$tokens = getAllTokens($filename); | |
if (isset($tokens[$token])){ | |
renewToken($filename,$token); | |
return TRUE; | |
} else { | |
return FALSE; | |
} | |
} | |
header('Content-Type: text/plain; charset=utf-8'); | |
if($needNewToken){ | |
echo newToken($tokensFilename); | |
} else { | |
if($token === FALSE){ | |
// PHP apparently passes the string but web server might not display | |
// So we'll echo as well | |
$errmsg = 'Token not received'; | |
header($errmsg, true, 404); | |
echo $errmsg; | |
} else { | |
if(isTokenValid($tokensFilename,$token,$maxAge)){ | |
echo 1; | |
} else { | |
echo 0; | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment