Php 通过URL$\u GET参数发送密钥

Php 通过URL$\u GET参数发送密钥,php,encryption,Php,Encryption,我有一个API,可以将url吐出到我网络上的重定向页面。url看起来像这样: http://mydomain.com/offers.php?country=US&offerID=5555 还有一些其他参数,但这就是它的jist。问题是,用户正在滥用它,并用机器人创建自己的点击。我想创建一个密钥系统,强制用户使用来自API的链接,这样它就不会被滥用 大概是这样的: http://mydomain.com/offers.php?country=US&offerID=5555 ap

我有一个API,可以将url吐出到我网络上的重定向页面。url看起来像这样:

http://mydomain.com/offers.php?country=US&offerID=5555
还有一些其他参数,但这就是它的jist。问题是,用户正在滥用它,并用机器人创建自己的点击。我想创建一个密钥系统,强制用户使用来自API的链接,这样它就不会被滥用

大概是这样的:

http://mydomain.com/offers.php?country=US&offerID=5555
api.php

<?php
$random_number=mt_rand(1,100);
$url="http://mydomain.com/offers.php?country=US&offerID=5555&key=".$random_number;
echo $url;
?>

offers.php

<?php
$key=$_GET['key'];
if($key<1 || $key>100)
die("Invalid key!");
?>

这显然是一个相当愚蠢的解决方案,因为它只使用了一个随机数…但希望您看到我试图实现的目标

我的想法是按小时对日期字符串进行加密,并使用静态隐藏密钥对其进行加密。这将使关键每小时都发生变化,而且对欺诈者来说将更加困难。唯一的问题是,如果有人在9:59从API获得url,它将在10:00过期,这太短了

最好的方法是什么?(理想的)关键应该是

  • 动态-它应该经常更改
  • 轻量级-不能花费大量资源只检查密钥
  • 很难破解/模拟

你有什么建议

存储当前用户会话的一次性使用哈希怎么样?

我是这样做的。我不推荐这是一个安全或有效的解决方案,只是一些简单的,防止用户篡改我的网址

public static function hashArray($arr, $timestamp)
    {
        $salt = "my-salt-here";
        $md5 = md5(http_build_query($arr) . $salt . $timestamp);
        return $md5;
    }


 //build the url
$timestamp = date("Y-m-d H"); //links will last for about two hours
//if you want single-use links, you can add a random number to params

$params = ['offer'=>10, 'country'=>'US'];
$params['hash']=hashArray($params, $timestamp); //build hash and add it
$url = 'http://my-domain.com/click.php?'.http_build_query($params);


//check the hash
public static function checkHash($params, $hash)
    {
       //allow current or previous hour
        return $hash === hashArray($params, date('Y-m-d H')) 
               || $hash === hashArray($params, date('Y-m-d H', time()-3600)) 
    }

$params=$_GET;
$hash = isset($params['hash']) ? $params['hash'] : '';
unset($params['hash']);
checkHash($params, $hash);

如果无法使用会话,还有哪些替代方案可用?您是如何解决此问题的?思想共享?我用一个附加的当前小时时间戳和一个附加的salt散列了所有参数。在接收端,我根据当前小时和前一个小时的时间检查了哈希值。只是为了让我明白你的意思。1-您没有使用会话。2您使用了$_GET参数(数据哈希+小时时间戳+salt)并重定向到具有此url的另一个页面。3。在接收页面上(您已经知道配置文件中的salt BCO?),您从哈希中提取时间,并与范围内的当前时间进行比较?为什么你不能将盐作为隐藏字段保存在接收页面中?对不起,如果我的问题不好?如果我把你的解决方案添加到你的帖子里可以吗。我认为它很有用。如果我把你的解决方案添加到你的帖子里可以吗。我认为它有用吗?2.你用了什么样的杂凑法?bcrypt?还是仅仅是md5?3.不是当前小时-前一小时,而是时间+30秒?接收页面/表单中的隐藏字段是个坏主意吗?感谢您添加您的答案,以方便他人。我目前没有这个问题,但我非常感谢有机会了解更多关于获取URL的信息。只是想知道。。。你为什么允许有两个小时的时间?有什么特别的原因吗?只是我的特殊用例。我希望用户再次查询API,而不是继续使用相同的链接。同时,我想灵活一些,不要不必要地阻塞太多的交通。。。如果接收页面有一个表单(不应直接访问),该哈希(从url中的get参数提取)是否可以用作隐藏字段,以便在表单作为post提交时进行检查?我理解使用session+post来达到这样的目的,但我想知道你的方法是否也可以使用?在session+post场景中,令牌(比如散列)位于隐藏字段中,然后发布并与会话值进行比较。在您的场景中,get中的哈希是否可以用于要发布并与自身进行比较的隐藏字段中?因为没有使用会话?