apache 防止直接访问 PHP 页面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/185483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prevent direct access to a PHP page
提问by syaz
How do I prevent my users from accessing directly pages meant for ajax calls only?
如何防止我的用户直接访问仅用于 ajax 调用的页面?
Passing a key during ajax call seems like a solution, whereas access without the key will not be processed. But it is also easy to fabricate the key, no? Curse of View Source...
在 ajax 调用期间传递密钥似乎是一种解决方案,而没有密钥的访问将不会被处理。但是制作钥匙也很容易,不是吗?查看源代码的诅咒...
p/s: Using Apache as webserver.
p/s:使用 Apache 作为网络服务器。
EDIT: To answer why, I have jQuery ui-tabs in my index.php, and inside those tabs are forms with scripts, which won't work if they're accessed directly. Why a user would want to do that, I don't know, I just figure I'd be more user friendly by preventing direct access to forms without validation scripts.
编辑:为了回答为什么,我的 index.php 中有 jQuery ui-tabs,在这些选项卡中是带有脚本的表单,如果直接访问它们将无法工作。为什么用户会想要这样做,我不知道,我只是想通过防止直接访问没有验证脚本的表单,我会更加用户友好。
回答by Jeremy Ruten
There is no way of guaranteeing that they're accessing it through AJAX. Both direct access and AJAX access come from the client, so it can easily be faked.
无法保证他们通过 AJAX 访问它。直接访问和 AJAX 访问都来自客户端,因此很容易被伪造。
Why do you want to do this anyways?
你为什么要这样做?
If it's because the PHP code isn't very secure, make the PHP code more secure. (For example, if your AJAX passes the user id to the PHP file, write code in the PHP file to make sure that is the correct user id.)
如果是因为 PHP 代码不是很安全,请使 PHP 代码更安全。(例如,如果您的 AJAX 将用户 ID 传递给 PHP 文件,请在 PHP 文件中编写代码以确保这是正确的用户 ID。)
回答by Eran Galperin
As others have said, Ajax request can be emulated be creating the proper headers. If you want to have a basic check to see if the request is an Ajax request you can use:
正如其他人所说,可以通过创建正确的标头来模拟 Ajax 请求。如果您想进行基本检查以查看请求是否为 Ajax 请求,您可以使用:
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
//Request identified as ajax request
}
However you should never base your security on this check. It will eliminate direct accesses to the page if that is what you need.
但是,您永远不应该将您的安全性建立在此检查上。如果您需要,它将消除对页面的直接访问。
回答by Draemon
It sounds like you might be going about things the wrong way. An AJAX call is just like a standard page request, only by convention the response is not intended for display to the user.
听起来您可能会以错误的方式处理事情。AJAX 调用就像标准页面请求一样,只是按照惯例,响应不打算显示给用户。
It is, however, still a client request, and so you must be happy for the client to be able to see the response. Obfuscating access using a "key" in this way only serves to complicate things.
然而,它仍然是一个客户端请求,因此您必须为客户端能够看到响应而感到高兴。以这种方式使用“密钥”混淆访问只会使事情复杂化。
I'd actually say the "curse" of view source is a small weapon in the fight against security through obscurity.
我实际上会说视图源的“诅咒”是通过默默无闻来对抗安全的小武器。
So what's your reason for wanting to do this?
那么你想这样做的原因是什么?
回答by Cristian Vat
If the browser will call your page, either by normal request or ajax, then someone can call it manually. There really isn't a well defined difference between normal and ajax requests as far as the server-client communication goes.
如果浏览器将通过普通请求或 ajax 调用您的页面,那么有人可以手动调用它。就服务器-客户端通信而言,普通请求和 ajax 请求之间确实没有明确定义的区别。
Common case is to pass a header to the server that says "this request was done by ajax". If you're using Prototype, it automatically sets the http header "X-Requested-With" to "XMLHttpRequest" and also some other headers including the prototype version. (See more at http://www.prototypejs.org/api/ajax/optionsat "requestHeaders" )
常见的情况是将一个标头传递给服务器,上面写着“这个请求是由 ajax 完成的”。如果您使用 Prototype,它会自动将 http 标头“X-Requested-With”设置为“XMLHttpRequest”以及其他一些标头,包括原型版本。(请参阅http://www.prototypejs.org/api/ajax/optionsat "requestHeaders" 处的更多信息)
Add: In case you're using another AJAX library you can probably add your own header. This is useful for knowing what type of request it was on the server side, and for avoiding simple cases when an ajax page would be requested in the browser. It does not protect your request from everyone because you can't.
添加:如果您使用另一个 AJAX 库,您可以添加自己的标头。这对于了解服务器端的请求类型以及避免在浏览器中请求 ajax 页面的简单情况很有用。它不会保护您的请求免受所有人的侵害,因为您不能。
回答by Kzqai
COOKIES are not secure... try the $_SESSION. That's pretty much one of the few things that you can actually rely on cross-page that can't be spoofed. Because, of course, it essentially never leaves your control.
COOKIES 不安全...试试 $_SESSION。这几乎是您实际上可以依靠无法欺骗的跨页面的少数事情之一。因为,当然,它基本上永远不会脱离您的控制。
回答by foxybagga
thanks, albeit I use
谢谢,虽然我用
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(IS_AJAX) {
//Request identified as ajax request
}
cheers!
干杯!
回答by Jeroenv3
In the javascript file that calls the script:
在调用脚本的 javascript 文件中:
var url = "http://website.com/ajax.php?say=hello+world";
xmlHttp.open("GET", url, true);
xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
then in the php file ajax.php:
然后在 php 文件 ajax.php 中:
if($_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest") {
header("Location: http://website.com");
die();
}
Geeks can still call the ajax.php script by forging the header but the rest of my script requires sessions so execution ends when no valid session is detected. I needed this to work in order to redirect people with expired hybridauth sessions to the main site in order to login again because they ended up being redirected to the ajax script.
Geeks 仍然可以通过伪造标头来调用 ajax.php 脚本,但我的脚本的其余部分需要会话,因此在未检测到有效会话时执行结束。我需要这样做才能将具有过期混合验证会话的人重定向到主站点,以便再次登录,因为他们最终被重定向到了 ajax 脚本。
回答by Antony Carthy
Pass your direct requests through index.php and your ajax requests through ajax.php and then dont let the user browse to any other source file directly - make sure that index.php and ajax.php have the appropriate logic to include the code they need.
通过 index.php 传递您的直接请求,通过 ajax.php 传递您的 ajax 请求,然后不要让用户直接浏览到任何其他源文件 - 确保 index.php 和 ajax.php 具有适当的逻辑来包含他们需要的代码.
回答by Antony Carthy
This definitely isn't useful for securing something.. but I think this could be of use if you wanted to have say a php page that generated a whole page if the page was not requested by ajax but only generate the part that you needed returned when ajax was used.. This would allow you to make your site non ajax friendly so if say they click on a link and it's supposed to load a box of comments but they don't have ajax it still sends them to the page that is then generated as a whole page displaying the comments.
这对于保护某些东西绝对没有用..但是我认为如果您想说一个 php 页面会生成整个页面,如果 ajax 没有请求该页面但只生成您需要返回的部分,这可能有用当使用 ajax 时.. 这将允许您使您的网站非 ajax 友好所以如果说他们点击一个链接并且它应该加载一个评论框但他们没有 ajax 它仍然将它们发送到页面然后生成一个显示评论的整个页面。
回答by Eric Tuttleman
Not sure about this, but possibly check for a referrer header? i think if someone manually typed in your url, it wouldn't have a referrer header, while AJAX calls do (at least in the quickly test I just did on my system).
对此不确定,但可能会检查引用标头?我认为如果有人手动输入您的 url,它不会有引用标头,而 AJAX 调用有(至少在我刚刚在我的系统上进行的快速测试中)。
It's a bad way of checking though. Referrer can be blank for a lot of reasons. Are you trying to stop people from using your web service as a public service or something?
虽然这是一种不好的检查方式。由于很多原因,Referer 可能是空白的。您是否试图阻止人们将您的网络服务用作公共服务之类的?
After reading your edit comments, if the forms will be loaded via ajax calls, than you could check window.location to see if the url is your ajax form's url. if it is, go to the right page via document.location
阅读您的编辑评论后,如果表单将通过 ajax 调用加载,那么您可以检查 window.location 以查看 url 是否是您的 ajax 表单的 url。如果是,请通过 document.location 转到正确的页面

