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

时间:2011-09-06 08:43:55

标签: php json api .htaccess

我正在构建一个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?

非常感谢提前!

1 个答案:

答案 0 :(得分:0)

.htaccess [OR]中,RewriteCond的效果与我认为您使用它的方式不同。所有RewriteRule适用于下一个RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule .* dispatcher.php ,因此不需要'或'。其次,您还需要将API请求推送到某种调度程序文件的规则,例如:

API::getClients()

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

  • 检查身份验证
  • 找出要查询的API
  • [检查参数](如果您在调度员中实现此功能由您决定)
  • 调用API函数
  • 将结果作为JSON
  • 返回

希望你抓住我的漂移:)