用PHP/MYSQL构建安全的公共API

用PHP/MYSQL构建安全的公共API,php,mysql,api,Php,Mysql,Api,我目前正在为一个非常繁忙的互联网网站构建一个API。它是用PHP和MySQL编写的。这是我正在编写的第一个API,它允许人们远程访问他们的帐户。一旦API上线,开发人员将能够从中编写自己的工具 现在我有了API,但我不确定它是否完全安全 一个有效的URL示例是:http://domain.com/api.php?api_option=list&api_user_name=USERNAME&api_user_password=PASSWORD USERNAME:将是用户的实际用户名 PASSWOR

我目前正在为一个非常繁忙的互联网网站构建一个API。它是用PHP和MySQL编写的。这是我正在编写的第一个API,它允许人们远程访问他们的帐户。一旦API上线,开发人员将能够从中编写自己的工具

现在我有了API,但我不确定它是否完全安全

一个有效的URL示例是:
http://domain.com/api.php?api_option=list&api_user_name=USERNAME&api_user_password=PASSWORD

USERNAME
:将是用户的实际用户名

PASSWORD
:将是其实际密码的MD5编码字符串

如果详细信息匹配,则返回结果,如果不匹配,则返回错误

所有外部
$\u GET
输入都会得到
mysql\u real\u escape\u string()
处理

我想让事情保持简单,但我不确定这种方式是否是一种安全的方式,可以让一个公共API直接访问用户帐户数据


非常感谢您的意见和建议。

出于对互联网的热爱,请不要这样做。我恳请您花时间为您的API实现OAuth。请求你了


看看这个:

不要使用密码来清除API,即使它是编码的,尤其是在MD5中编码的情况下。此外,我也不会使用用户用户名。让用户生成一个密钥。您让某人能够知道访问用户帐户所需的50%,而MD5有许多站点,您可以将其反转并找到密码匹配。密钥当然是最好的方法,因此开发人员可以为安全目的进一步重新生成密钥。始终考虑安全性。

使用HMAC_SHA1和用户密码对请求进行签名如何?例如,您的URL:
http://domain.com/api.php?api_option=list&api_user_name=USERNAME&api_user_password=PASSWORD

添加时间戳和/或随机字符串(nonce)并构建规范化的基本字符串:

$base_string = "api_option=list&api_user_name=USERNAME&timestamp=1296875073&nonce=hgg65JHFj";
$signature = hmac_sha1($base_string, PASSWORD);
那么新的URL将是:


您的服务器所做的是获取所有选项(不包括签名),然后使用相同的方法生成签名,并将其与客户端发送的签名进行比较,后者应该是相同的。

在URL中设置密码哈希不是一个好主意。一个更好的方法可能是拥有一个API密钥,它在用户和API之间调用某种形式的身份验证。我在数据库中存储了一个auth密钥,并且用户id与之链接。此设置可以工作,但用户仍然需要获得此密钥,如果其他人使用此API构建工具,则用户需要能够使用其注册的用户名/密码登录。因此,我仍然不知道如何绕过一个可以同时接收用户名和密码的初始$\u get url来远程生成API密钥。建议:1。至少使用超文本传输协议安全(HTTPS)而不是HTTP。2.通过POST发送登录(不是通过URL/GET,因为它们将出现在日志中)您真的必须使用OAuth吗?我不喜欢它…(尽管我同意上面的方法不好/不安全)@o1iver:我推荐OAuth只是因为它非常普遍,而且已经有很多关于它的文章,特别是因为OP显然不能被信任提出自己的安全实现。不过,任何基于令牌的授权系统都比他目前所做的要好。好吧,我同意你关于基于令牌的身份验证的看法,我只是不喜欢OAuth:-)@o1iver:那很好,哈哈。请随意添加您自己对令牌身份验证系统的推荐,我很好奇其他人使用什么(我只是有幸使用了OAuth和OAuth衍生物)。在发现我不喜欢OAuth后,我目前正在做一些事情。但是我现在只是在尝试不同的事情…所以我不能做出太多贡献:-)嗨,阿文,谢谢你的回复。我开始了解大概情况了。请您对以下设置发表意见。1.网站管理员注册使用独特的网站管理员api密钥2$_POST请求只能通过https发送到apilogin.php,https包括“用户名”、“密码”、“网站管理员api密钥”、“时间戳”。3.php将运行$base\u string=“username+timestamp+webmaster\u api\u key”$签名=hash_hmac('sha512',$base_string,$password);如果登录详细信息有效,则返回$signature。这个$signature记录在会话数据库中,用户id链接到它。另外,我也不能100%确定会话的过期时间。我猜在某些情况下,用户希望长时间保持登录状态。此外,用户可能希望使用各种工具保持登录状态,这意味着数据库中只存储1个用户的各种会话。除了有人单击注销外,什么会使会话过期?