内部+外部API -保护API并调用内部API


internal + external API - securing the API and calling the internal API

我正在构建一个API来为网站提供动力,以及使应用程序可用,尽管这是我的第一个API,我发现了一些问题领域,并希望在可能的情况下得到一些建议/提示。

我计划让外部API使用用户名/密码和API密钥进行身份验证,但是,我真的不希望内部API具有这两个。这是因为我希望将来可能分发脚本,并且不希望有人找到用于访问内部API的任何访问代码,在那里他们可以使用这些访问代码来访问外部API(使用该脚本的任何站点)。

理想情况下,我想把这两个api放在一起,使管理它们更容易。

保护对API的直接访问,这样就不会有人试图直接包含它(在.htaccess中):

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^.*$ - [R=401,L]

我收集访问外部API,需要做以下事情(在PHP中):

$url = "http://www.mydomain.com/script/api.php";
$username = "username";
$password = "password";
$apikey = "12345678901234567890";
$postfields = array();
$postfields["username"] = $username;
$postfields["password"] = md5($password);
$postfields["apikey"] = md5($apikey);
$postfields["action"] = "getclients";
$postfields["format"] = "json";
$query_string = "";
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$jsondata = curl_exec($ch);
if (curl_error($ch)) die("Connection Error: ".curl_errno($ch).' - '.curl_error($ch));
curl_close($ch);
$array_out = json_decode($jsondata);

然而,我不确定(确切地)在我的后端包含内部API的最佳方式-我曾认为也许我可以这样做(在PHP中):

$postfields = array();
$postfields["action"] = "getclients";
$postfields["format"] = "json";
ob_start();
include("script/api.php");
$array_out = json_decode(ob_get_contents());
ob_end_flush();

然而,由于我在API中发送标题header ("content-type: text/json charset=utf-8");, Firefox只希望我保存输出而不是传递它。我试过不发送头,但是所有的API变量都通过包含它的页面传递-这是我不想要的。

我的问题是:

  • 是否有更好的方法在PHP中获得JSON输出(内部访问)?
  • .htaccess文件是否足以保护API不被第三方站点包含?
  • 外部认证是否充分?
  • 是访问内部API正确的方式来做到这一点,如果我计划分发脚本?

提前感谢!

在你的.htaccess, [OR]不工作的方式,我认为你使用它。所有的RewriteCond都适用于下一个RewriteRule,因此不需要"或"。其次,您还需要规则将API请求推送到某种调度器文件,例如:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* dispatcher.php

我不认为通过cURL等内部调用API函数是有意义的——特别是因为你必须通过身份验证等。在我看来,有一个(面向对象)的集合会更有意义。你可以直接调用内部的api,比如API::getClients()。然后构建一个调度程序脚本,将所有传入的Ajax请求推送到该脚本。该脚本将执行以下操作:

  • 检查认证
  • 查找查询的API
  • [检查参数](如果你在你的调度程序中实现这个由你决定)
  • 调用API函数
  • 以JSON形式返回结果

希望你明白我的意思