允许跨域Ajax请求

39
在我的项目中,我需要允许其他人向我的脚本发送ajax请求。因此,外部请求可能来自其他网站和域,也可能来自浏览器扩展程序。
我只是在脚本的顶部添加了这两行简单的代码来让他们做到这一点:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');  

现在我的问题是:我是否忽略了任何安全考虑?这个简单的解决方案是否会引起严重问题?
如果是,那么有更好的解决方案是什么?

感谢回复。


你应该记住,如果你的脚本泄露了任何个人信息,现在任何人都可以窃取它。 - zerkms
你能解释更多吗?这是如何可能的? - Aliweb
这些头文件有这么神奇的作用吗?以前从不知道。 - Shiplu Mokaddim
@ali:如果我创建一个执行Ajax请求的页面,给你一个链接并将其发送给你-那么我可以获得与该端点相同的任何内容。 - zerkms
你想让外部请求访问什么?听起来你应该编写一个API。 - PieSub
这类似于URL缩短器,但几乎是不同的工作。用户应该能够从任何地方提交他们的数据并获得响应。 - Aliweb
4个回答

19

如上所述,任何人都可以随时向您的页面发送请求:因此,您需要关注的主要安全问题是验证用户输入,并仅显示可供公众消费的信息。但这适用于所有脚本。

在验证用户输入之后,您需要集中关注的两个主要问题是:

  1. 您可能遇到的问题是用户将信息接收到其脚本中。根据浏览器(甚至是同一浏览器的不同版本),有不同的安全规则来防止它们获取信息。一个常见的解决方案是将返回的信息作为“JSONP”提供,即将返回值包装为客户端可以执行的函数调用。以下是一个快速示例(摘自http://www.geekality.net/2010/06/27/php-how-to-easily-provide-json-and-jsonp/)。为了进一步加强安全性,您可以坚持要求所有查询均为JSONP,并拒绝未发送回调函数的任何人。

.

<?php

header('content-type: application/json; charset=utf-8');
$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
echo $_GET['callback'] . '('.json_encode($data).')';

?>
  1. 有人滥用您的服务过于频繁调用。解决方法是陷阱IP地址,如果从一个IP地址接收到太多的调用,则拒绝。不是万无一失的,但这是一个开始。

需要记住的其他因素:

  • 由您的脚本设置的cookie和其他标头可能会被忽略
  • 同样适用于会话

始终注意用户输入!https://dev59.com/8HVC5IYBdhLWcg3w-WSs - PieSub

1

就像zerkms所说的,如果他们只是“访问”您的php页面,他们将能够看到它所输出的任何内容。 如果可能的话(不确定是否可以),它还将允许不需要的人甚至在本地主机上创建自己的表单并通过AJAX提交以获取他们想要的响应... 如果这对您来说没问题,并且信息模糊/无害... 那么我想它会是“安全”的。这是一种不安全的方法来获取/传输敏感信息。


好的,这个脚本提供的信息和 echo() 都不是 敏感 的。我想知道是否有更好的解决方案。 - Aliweb
如果它不是“敏感”的,并且在理论上可能,我认为除了服务器端通信之外,没有比这更好的解决方案,在那里没有客户端获取信息。例如,一个可能调用您自己服务器上的php文件的ajax调用,该php文件执行工作,联系其他服务器并返回结果,就客户端而言,所有事情都发生在您的端口,没有第三方参与。 - Zak

1

这对我来说完美地运作了。

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Allow: GET, POST, OPTIONS, PUT, DELETE");
$method = $_SERVER['REQUEST_METHOD'];
if($method == "OPTIONS") {
    die();
}

0
private function set_headers() {
    header("HTTP/1.1 ".$this->_code." ".$this->get_status_message());
    header("Content-Type:".$this->_content_type);           
    header("Access-Control-Allow-Origin: *");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接