我的应用程序包含几个可通过AJAX访问的PHP端点。问题是它们也可以通过向同一端点发出HTTP请求的任何人访问它们。我可以按this answer中的说明添加HTTP_X_REQUESTED_WITH
和HTTP_REFERER
的支票,但这些可能会被欺骗。我可以添加一个需要随请求发布的密钥,但是查看javascript和/或控制台的任何人都可以看到此密钥。这里有什么解决方案?
答案 0 :(得分:4)
人们通常认为,因为他们使用Ajax请求,常规sessions
不起作用。他们是这样。
如果您有一个端点可以从数据库中删除源代码中可见的内容,例如:
example.com/user/1/delete
您可以像在浏览器中使用非Ajax HTTP请求一样保护来自未经过身份验证的用户的此请求。使用sessions。如果用户具有删除用户的权限,则此路由将起作用,否则返回错误(或不执行任何操作)。
您还可以使用OAuth保护API。这里有一个很棒的文档解释了它的工作原理:http://tatiyants.com/using-oauth-to-protect-internal-rest-api/
答案 1 :(得分:3)
如果您的应用和api位于不同的域上,例如app.example.com
和api.example.com
,大多数答案都无济于事 - 在这种情况下,会话无法正常工作,您必须转向OAuth,这对于这样一个简单的问题来说是一个很大的锤子。
以下是我要做的事情:
我假设您拥有数据库中的用户和user_id=12345
这样的唯一标识符。我还假设你在数据库中有你的工作,他们也有job_id=6789
这样的唯一ID。
首先在app.example.com
上用Blowfish快速简单地加密这两个ID:
$secret_uid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($user_id));
$secret_jid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($job_id));
我假设你的终端有点像这样:
api.example.com/jobs/delete/<job_id>/<user_id>
现在从Ajax中调用该端点,而不是使用普通ID调用
api.example.com/jobs/delete/6789/12345
您使用加密ID调用它:
api.example.com/jobs/delete/6A73D5B557C622B3/57F064C07F83644F
在软件的API端,您可以解密参数:
$jid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_1>);
$uid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_2>);
现在,您可以在数据库中搜索uid
和jid
,然后执行您计划执行的任务。确保用户当然只能删除自己的工作。
我承认这不是一个100%的解决方案,但它让攻击者有很多猜测工作 - 他必须猜测user_id和匹配的job_id,加密算法和你的秘密。它无法阻止数百万次暴力攻击尝试匹配对,但它确定了对您有利的几率(并且您应该对端点进行某种配额限制保护)。
祝你好运!答案 2 :(得分:2)
没有。如果你给某人一些数据,那么他们可以用他们喜欢的任何方式处理它。您无法控制它离开服务器后发生的情况。
同样,您无法控制他们发送到端点的数据。
答案 3 :(得分:0)
对于开发人员来说,为API或Web服务进行身份验证非常重要。 dchacke 和 BugHunterUK 给出了完美答案,我只想向您展示我用来制作非常简单的简单代码易于使用的身份验证。
为身份验证添加会话
您可以为API添加会话和会话超时,这样,只有您的应用可以使用此功能,您可以在加载应用的首页时启动会话,您可以设置超时并限制不同用户的不同服务会话。
一般想法如何做到
<?php
if(!empty($_SESSION['api_session']) && $_SESSION['api_session'] == 'usertype'){
//usertype comprise of what access you want to give
//guest, registered user, stack holder, admin etc.
...
header('Content-Type:application/json;');
echo json_encode($output);
}