Проверьте запрос curl CURLOPT_HTTPHEADER на стороне сервера - PullRequest
0 голосов
/ 19 ноября 2018

Я разработал небольшой веб-сервис, который будет принимать пользовательский запрос и возвращать данные в виде ответа json. Все работает нормально. Но мне было интересно, как установить и сравнить Токен авторизации со стороны клиента как часть заголовка curl. Это мой код для отправки запроса. Тем не менее, я не установил никакой проверки на FetchData.php. Я хочу реализовать это на FetchData.php. Как это реализовать?

$query = "select * from product_details where id = 2";
$query_params = array("query" => $query); 
$url = "http://localhost/api/fetchData.php?" . http_build_query($query_params, '', "&");
$curl = curl_init();
$token = 'ABCD123456';
$header[] = 'Authorization: Token '.$token;
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_HTTPGET=>1,
CURLOPT_FAILONERROR=> 1,
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_HTTPHEADER=>$header
));

$resp = curl_exec($curl);
if($resp === false)  
{
    $responseJson = new stdClass(); 
    $responseJson->status =  "FAILED";
    $responseJson->message = 'Send error: ' . curl_error($curl);
    throw new Exception(curl_error($curl)); 
}
else{
    $resp = curl_exec($curl);
}

В приведенном выше коде я добавил этот токен авторизации. Но на самом деле это не было установлено на стороне сервера, я имею в виду в fetchData.php.

$token = 'ABCD123456';
$header[] = 'Authorization: Token '.$token;

Итак, мой вопрос: как настроить этот токен авторизации в fetchData.php и проверить токен, который был на стороне клиента? Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 20 ноября 2018

если есть только 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)
...