Well I have two tokens. A hash generated when the user logs in (stays the same for life of session), and one for forms. The form token is generated every request since it uses a timestamp in the hash. But since the timestamp and timeout are included with the hash, I can check if the hash is valid. Some people suggests storing tokens in session, and removing them or expiring them as they are used. This method is similar but doesn't require storing lots of tokens in session. All the info is encapsulated in the token itself. The idea came from this article:
https://josephscott.org/archives/2013/08/better-stateless-csrf-tokens/
Heres a code sample. getUserKey() returns unique user data from database/session and hash() is just a generic modern hash method:
public function getFormToken($str = "", $timeout = 900)
{
$hash_time = microtime(true);
$key = $this->getUserKey();
$toHash = $str . $hash_time . $timeout . $key;
$hash = $this->hash($toHash);
return "{$hash}-{$hash_time}-{$timeout}";
}
public function verifyFormToken($str = "", $token = "")
{
list($hash, $hash_time, $timeout) = explode("-", $token);
if(empty($hash) || empty($hash_time) || empty($timeout)) {
return false;
}
if( microtime(true) > $hash_time + $timeout) {
return false;
}
$key = $this->getUserKey();
$checkString = $str . $hash_time . $timeout . $key;
$checkHash = $this->hash($checkString);
if($checkHash === $hash) {
return true;
}
return false;
}