创建PHP API:检查API请求来自哪个服务器

Jim*_*Lin 11 php api dns curl request

我正在为网站创建一个PHP API,我想限制对我们服务器上注册的域的API访问(以防止滥用API).所以,这是我现在的方法,而且它应该在纸上看起来相当不错.

  1. API设置为api.example.com.
  2. 想要使用API​​的用户向我们注册,添加他的域并获取API密钥.
  3. API的用户将使用他的API密钥(通过加密他的请求的数据mcrypt),并发送它,经由cURLapi.example.com.
  4. 我的服务器检查此API请求来自哪个域,并将该域与数据库中的API密钥进行匹配.如果有API密钥,API会mcrypt使用该密钥解密请求,然后使用相同的方法加密并发送结果.

我坚持第4步.最初,我打算使用HTTP_REFERER来检查它,但是因为cURL默认情况下没有发送一个,所以它很容易在用户端代码中伪造(据我记得CURLOPT_REFERER),我被困在这里.

有没有方法可以知道此API请求来自哪个域?我看到它可以用一些流行的API来完成,比如reCAPTCHA.由于共享主机(它们具有相同的IP),检查_SERVER ["REMOTE_HOST"]实际上不是一个选项,因此这将无法防止滥用(无论如何主要来自共享服务器).

有没有这样的方法来检查它?谢谢!

ani*_*son 7

@Shafee有一个好主意,只需要一些调整.我们专注于API调用的可见部分,即API密钥.这是可见的网址,并告诉API 请求的数据.而不是试图阻止其他人窃取此密钥并使用他们截获的域运行他们自己的cURL调用,我们可以 "只添加"混合的另一个密钥,这个对这些拦截器不可见.我不是说停止检查请求来自何处,它仍然是在脚本早期发出无效请求的好方法,但是使用第二个密钥,您保证只有请求数据的人才知道如何获取数据(你相信他们不会把它交给任何人).

因此,当用户注册密钥时,您实际上是在为用户分配两个不同的密钥.
API_KEY - 将您连接到您的域的公钥.系统会查找提供的域和密钥,以便查找下一个密钥.
MCRYPT_KEY - 这是用于通过Mcrypt实际加密该数据的密钥.由于它是加密数据,因此只有请求者和服务器才知道它是什么.您使用密钥加密数据并将带有API密钥的加密输入发送到服务器,服务器找到通过API密钥和已提供的域(和IP)解密该输入所需的密钥.如果他们没有使用正确的密钥加密数据,那么使用正确的密钥进行解密将返回乱码并且json_decode()调用将返回NULL,从而允许脚本简单地返回"invalid_input"响应.

最终使用这种方法,我们甚至需要检查请求来自哪里(域/ IP)?使用这种方法实际上归结为API用户没有向其他用户泄露他们的API/MCRYPT密钥对,类似于不泄露您的用户名/密码.即便如此,任何网站都可以轻松注册以获取自己的密钥对并使用API​​.另外需要注意的是,除非最终用户使用正确的用户名和密码登录,否则API甚至不会向其服务器返回任何有用的内容,因此他们的结尾将已经拥有该信息.我们的服务器真正返回的唯一新功能是成功验证用户后的电子邮件地址.话虽如此,我们甚至需要使用cURL吗?我们不能简单地使用file_get_contents('http://api.example.com/{$API_KEY}/{$MCRYPT_DATA}')吗?我意识到我在回答中提出了更多问题......