我正在构建一个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形式返回结果
希望你明白我的意思