php - 在服务器端验证curl CURLOPT_HTTPHEADER请求

标签 php rest curl http-head

我开发了一个小型网络服务,它将接受用户查询并将数据作为 json 响应返回。一切工作正常。但我想知道如何设置和比较 来自客户端的授权 token 作为curl header 的一部分。这是我发送请求的代码。我仍然没有在 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);
}

在上面的代码中我添加了这个授权 token 。但实际上这并没有在服务器端设置,我的意思是在 fetchData.php 中。

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

所以我的问题是如何在 fetchData.php 中设置此授权 token 并验证来自客户端的 token ?任何帮助将不胜感激。

最佳答案

如果只有 1 个 token ,您可以对其进行硬编码,

if(hash_equals(hash('sha384',$_SERVER['HTTP_AUTHORIZATION'],true),hash('sha384','the-real-token',true)){
    // correct token!

}else{
    // wrong token
}

但是,如果您有多个 token ,则应该将它们预先散列保存在数据库中,这是一个带有 token “foo”、“bar”和“baz”的 SQLite 示例:

$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)));
}

有了这个,您可以通过运行来检查 token 是否有效

$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 =(
}

现在您可能想知道

why bother hashing the tokens at all, why not just save them in plaintext?
这是为了防止计时攻击,哈希值会进行长度填充,因此黑客无法使用计时攻击来推断 token 的实际长度(这可以帮助攻击者执行暴力/字典攻击),并且哈希值之间没有相关性实际 token 、输入字符串以及定时攻击的正确位数,即使黑客设法推断出哈希值的前 8 位肯定是 10010111,它也会变得越来越困难找到一个字符串,对于推断出的每个位,散列到已知位+1,最终结果是使用定时攻击来攻击该方案应该是完全不可行的(至少使用 sha2-384)

关于php - 在服务器端验证curl CURLOPT_HTTPHEADER请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53377426/

相关文章:

python - NOAA Weather REST API 在使用 curl 请求时导致错误

php - php PDO 可以获取两个结果集吗?如果是,那么 1 个结果集或多于 1 个结果集哪个更好?

php - JS中的动态选择选项

php - 在哪里设置配置选项?启动()或注册()?单例()或绑定(bind)()

java - 重构不兼容 REST 的请求

asp.net - 如何在 IIS 10 上托管 ASP.NET Web API 2 项目

regex - 使用 curl 列出文件

php - Paypal PHP API 集成

php - 通过 yum 安装 php,包括 mysql 支持

jquery - 我应该如何使用 javascript 访问 Spring MVC Rest 服务?