What you could do is add a timestamp to the token key as when it was created plus the requesters IP and then when you decrypt the key check if the time falls between your allowed time or allow ip address.
example with fixed IP:
<?php
class csrf_check {
const SALT = '_SECRET_';
public function create_api_key()
{
return base64_encode($this->encrypt(time().'|'.$_SERVER['REMOTE_ADDR'])); // !change if you dont want IP check
}
public function check_api_key($key, $timeout = 5)
{
if (empty($key)) exit('Invalid Key');
$keys = explode('|', $this->decrypt(base64_decode($key)));
return (
isset($key, $keys[0], $keys[1]) &&
$keys[0] >= (time() - $timeout) &&
$keys[1] == $_SERVER['REMOTE_ADDR'] // !change if you dont want IP check
);
}
public function encrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
// hash
$key = hash('sha256', $key);
// create iv - encrypt method AES-256-CBC expects 16 bytes
$iv = substr(hash('sha256', $secret), 0, 16);
// encrypt
$output = openssl_encrypt($string, $method, $key, 0, $iv);
// encode
return base64_encode($output);
}
public function decrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
// hash
$key = hash('sha256', $key);
// create iv - encrypt method AES-256-CBC expects 16 bytes
$iv = substr(hash('sha256', $secret), 0, 16);
// decode
$string = base64_decode($string);
// decrypt
return openssl_decrypt($string, $method, $key, 0, $iv);
}
}
$csrf = new csrf_check();
//start example
$do = filter_input(INPUT_GET, 'do');
$key = filter_input(INPUT_GET, 'key');
switch ($do) {
//example.com?do=get - a key for the request
case "get": {
$key = $csrf->create_api_key();
echo '<a href="?do=check&key='.urlencode($key).'">Check Key ('.$key.')</a>';
} break;
//example.com?do=check - a key for the request
case "check": {
//key only lasts 30 secs & validate key passed
//example.com?do=check&key=MEV6NXk4UjVRQXV5Qm1CMjBYa3RZZUhGd2M0YnFBUVF0ZkE5TFpNaElUTT0=
echo 'Key ' . ($csrf->check_api_key($key, 30) ? 'valid' : 'invalid');
echo '<br><a href="?do=get">Get new key</a>';
} break;
default: {
echo '<a href="?do=get">Get Key</a>';
} break;
}