如何允许仅由站点调用 php 文件,而不是 Inspect Element 或 URL

Posted

技术标签:

【中文标题】如何允许仅由站点调用 php 文件,而不是 Inspect Element 或 URL【英文标题】:How to allow php files to only be called by site, not Inspect Element or by URL 【发布时间】:2019-01-30 08:00:05 【问题描述】:

我有很多 php 文件更新我的数据库,但我希望这些文件仅在我的代码中调用(通常通过 ajax)时才有效。

现在,如果我将 php 文件的 URL 放入,它会更新数据库,如果我将 ajax 代码放入检查元素,则数据库会更新。

我不希望人们乱用他们不应该更改的信息。

我该如何解决这个问题?

例如。

在其中一个文件中,我将 1 添加到 db 值。如果我将此文件的链接放在浏览器中,它会添加一个。如果我把 ajax 放到这个链接上,它也会更新数据库。这对网站的安全性非常不利。


编辑:我正在尝试实施评分最高的答案,但出现错误:

意外的标记“.”。属性名称“myreq”后面应该有一个“:”。

这是我的代码:

var myreq = new XMLHttpRequest();

$.ajax(
    headers: 
        myreq.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    
    url: 'http://myurl.php',
    data: ,
    type: 'post',
    success: function(output) 
    
);

我可能不得不将 myreq 部分放在 beforeSend 下而不是 headers 但 idk,我是新手。

【问题讨论】:

“通过 ajax 或其他方式” - 什么是 “另一种方式”?此外,如果您希望您的 PHP 脚本可以从前端访问(如 ajax),那么实际上没有办法 100% 阻止人们直接访问它们。您可以检查调用是否通过 Ajax,但这可能会被欺骗。您还可以实施一些 CSRF 保护,使其更加困难。此外,您不应允许 GET 请求更新数据。您应该使用 POST 或 PUT,这至少会停止通过浏览器进行直接访问。 您可以使用会话变量将呼叫识别为来自您的网页。但是,即使是有经验的黑客也可以调用。它会阻止普通用户调用它。 【参考方案1】:

如果您想阻止直接访问您的 php 文件并只允许 AJAX 调用,如Prevent Direct Access To File Called By ajax Function 问题所述:

您可以在服务器端使用此代码:

if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )

    // allow access....
 else 
    // ignore....
 

并将标头添加到客户端的 ajax 请求中:

var myreq = new XMLHttpRequest();
myreq.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 

使用此解决方案,您可以防止滥用在标准浏览器中打开该文件

但请记住:客户端的一切都可能被欺骗。因此,如果您想防止滥用,您需要更改更新数据库值的方式。或者至少添加 IP 检查或会话检查或验证码,以使黑客更难滥用......

在这个例子中,黑客可以欺骗 ajax 调用

PHP 7 更新:

感谢 Stephen R (For commenting) AS OF PHP 7 您可以用以下代码替换 If 语句以获得更简洁的代码:

if( ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? 0 ) === 'XMLHttpRequest' )

【讨论】:

我试试,谢谢。但是,如果我这样做,黑客只能使用无法通过验证码的方法来通过吗?所以如果我同时实现这个方法和IP Check或Captcha,黑客将无法通过? @Patrick 你只会让黑客更难做到这一点,很难但并非不可能。最好的方法是改变你更新数据库的方式,例如一种身份验证方式。或者类似的东西...... 对于 PHP 7 更简洁的 if()if( ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? 0 ) == 'XMLHttpRequest' ) ... 更正:'XMLHttpRequest' == 0 计算结果为真。请改用空字符串''if( ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' ) == 'XMLHttpRequest' )。对不起! 或者你可以做一个严格的比较:=== 'XMLHttpRequest'。请参阅此处了解发生这种情况的原因:***.com/questions/6843030/…【参考方案2】:

对于您编辑的代码,存在几个问题。您不需要XMLHttpRequest。如果您将它们作为数组提供,jQuery 将添加标题。

另外,您需要在 headers 元素后加一个逗号。请注意,ajax 函数的参数是一个数组,而 headers 只是该数组中的元素之一。

尝试以下方法:

$.ajax(
    headers: 
        "X-Requested-With" : "XMLHttpRequest",
    ,
    url: 'http://myurl.php',
    data: ,
    type: 'post',
    success: function(output) 
    
);

【讨论】:

是的,它成功了,谢谢!我将支持您的答案,但我将不得不将另一个标记为正确。再次感谢!【参考方案3】:

您需要添加.htaccess 文件。

<Files ~ "^.*">
  Deny from all
</Files>

<Files ~ "^index\.php|css|js|.*\.png|.*\.jpg|.*\.gif">
  Allow from all
</Files>

这里它只允许 index.php 和所有 css/js/images 允许从浏览器直接 url 或 ajax 或从代码调用。

【讨论】:

用户仍然可以从浏览器地址栏调用php文件。 这不会阻止 Ajax 调用其他 php 文件吗?【参考方案4】:

如果您担心安全性,您应该要求进行某种帐户注册,以便您可以随请求发送一些身份验证数据(最好是令牌)。任何类型的客户端身份验证(我能想到的要求调用来自您的站点的唯一原因)都是一个糟糕的主意

【讨论】:

以上是关于如何允许仅由站点调用 php 文件,而不是 Inspect Element 或 URL的主要内容,如果未能解决你的问题,请参考以下文章

Jsonp代理示例,发送请求到我们自己的站点而不是sencha站点

如何将 PHP 会话数据保存到数据库而不是文件系统中?

Linux 如何设置只允许域名访问站点而禁止IP访问站点

php 如果我们有一个多站点,每个人都需要成为超级管理员(能够创建新站点)但不是每个人都应该被允许

可以通过文件夹而不是端口访问多个基于 laravel 的站点吗?

如何使用php而不是OOP自动包含文件?