если есть только 1 токен, вы можете просто жестко закодировать его,
if(hash_equals(hash('sha384',$_SERVER['HTTP_AUTHORIZATION'],true),hash('sha384','the-real-token',true)){
// correct token!
}else{
// wrong token
}
однако, если у вас есть несколько токенов, вы должны сохранить их предварительно хэшированные в БД, вот пример SQLite с токенами "foo", "bar" и "baz":
$db = new PDO('sqlite::memory:', '', '', array(
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
$db->exec('
CREATE TABLE tokens(id INTEGER PRIMARY KEY AUTOINCREMENT,
token TEXT,
hash BLOB);');
$stm=$db->prepare("INSERT INTO TOKENS(`token`,`hash`) VALUES(:token,:hash);");
$tokens=["foo","bar","baz"];
foreach($tokens as $token){
$stm->execute(array(':token'=>$token,':hash'=>hash('sha384',$token,true)));
}
с этим вы можете проверить, является ли токен действительным, запустив
$stm=$db->prepare("SELECT EXISTS(SELECT 1 FROM hashes WHERE hash=?);");
$stm->execute([hash('sha384',$_SERVER['HTTP_AUTHORIZATION'],true]);
if($stm->fetch(PDO::FETCH_NUM)[0]==="1"){
// valid token!
}else{
// invalid token =(
}
теперь вы можете задаться вопросом
зачем вообще хэшировать токены, а не просто сохранять их в незашифрованном виде?
речь идет о защите от временных атак, хэши выполняют заполнение по длине, поэтому хакеры не могут использовать временные атаки для вывода фактическая длина токенов (которая может помочь злоумышленникам в выполнении атаки методом грубой силы / словаря), и нет никакой корреляции между фактическим токеном, входной строкой и количеством правильных битов для атаки по времени, и даже если хакерам удается сделать вывод, что
the first 8 bits of the hash is definitely 10010111
, становится все труднее найти строку, которая хэширует известные биты + 1 для каждого бита, который выводится, в результате чего атака на эту схему с помощью временных атак должна быть совершенно невозможной (хотя бы с sha2-384)