【问题标题】:Control access to files based on DB values with PHP/Apache使用 PHP/Apache 根据数据库值控制对文件的访问
【发布时间】:2011-08-27 05:00:33
【问题描述】:

我想要什么

我正在创建一个系统,当用户上传图像时,它会转到文件夹 images,其中有图像的两个副本,一个拇指和一个更大的。

现在,当用户上传图片时,它会在 MySQL 数据库中插入一行的同时完成,其中图片获取一个 id,并且该行包含一个值,该值确定图片是否可供公众使用 (1只有拇指可用,两个都用 2 个)以及图像的所有者(管理员)。

我不想做的是,如果用户试图通过访问图像的 URL 来访问图像,并且数据库中的值表明它不应该是公开的,并且该用户的会话不是图片的所有者(管理员未登录)应该说图片未找到或访问被拒绝。

我的想象

如果可以用 php 完成,我想像这样:

//User tries to go to URL "images/IMAGE-ID_thumb.jpg"
if($img['access'] >= 1 || $_SESSION['admin_ID'] == $img['owner_ID']) {
  //Show image thumb
}
else {
  //Access denied
}

我也许可以将图像隐藏在 .htaccess 受保护的文件夹中,创建一个接受 URL 变量的 imgae_get.php,查看图像是否可用,如果可用则加载图像。我只是想避免必须反编译/重新编译映像和其他服务器耗电过程。

我的问题是,我可以这样控制图像吗?有没有办法让 php 脚本显示为它在内部加载的图像? 还是有可能比通过 PHP 有其他/更好的方法? (也许是 Apache?)任何建议都非常感谢。

【问题讨论】:

    标签: php apache file access-control


    【解决方案1】:
    //get_image.php
    
    //Do session/mysql checks as outlined in your code above.
    
    header("Content-Disposition: filename=$imagename.$filetype");
    header("Content-type: $mimetype");
    readfile(PROTECTED_IMAGE_FOLDER . "$imagename.$filetype");
    

    【讨论】:

      【解决方案2】:

      您可以使用DocumentRoot 中的“.htaccess”文件重定向对某些文件类型(或文件名,任何您可以正则表达式的内容)的所有请求:

      RewriteEngine On
      
      RewriteCond %{REQUEST_FILENAME} -s [OR]
      RewriteCond %{REQUEST_FILENAME} -l [OR]
      RewriteCond %{REQUEST_FILENAME} -d
      RewriteRule ^.*$ - [NC,L]
      RewriteRule \.(gif|jpg|jpeg|png)$ imageHandler.php [NC,L]
      

      您可以确定来自$_SERVER 超全局的原始请求,并使用适当的标头来提醒浏览器您正在返回图像。然后从磁盘读取图像(使用file_get_contents() 或类似的)并使用echo 将其写入浏览器,与输出HTML 的方式相同。

      【讨论】:

      • 谢谢,将您的答案与@tandu's 结合起来将是我的最终解决方案,实际上也将 php 隐藏在用户面前。 +1 :)
      【解决方案3】:

      .htaccess

      #mod_rewrite
      RewriteRule ^(.*)_(full|thumb).(jpg|png|gif)$ image.php?i=$1&type=$2&ext=$3
      

      HTML

      <img src="http://example.com/image-1_thumb.png" />
      =
      <img src="image.php?i=image-1&type=thumb&ext=png" />
      

      PHP (image.php)

      <?php 
      // do basic sanity checks on input
      $_GET['i'] = isset($_GET['i']) ? basename($_GET['i']) : null;
      $_GET['type'] = isset($_GET['type']) ? basename($_GET['type']) : null;
      //unsafe way
      //$_GET['ext'] = isset($_GET['ext']) ?  basename($_GET['ext']) : null;
      //safe way
      $_GET['ext'] = in_array($_GET['ext'], array('png','gif', 'png')) ? $_GET['ext'] : null;
      
      ## Do DB Checks on session to owner ect 
      /* $_GET
          [i] => image-1
          [type] => thumb
          [ext] => png
      */
      
      // then output
      if (file_exists('hiddenimagesfolder/images/'.$_GET['i'].'_'.$_GET['type'].'.'.$_GET['ext'])) {
          header("Content-Type:image/png");
          readfile('hiddenimagesfolder/images/'.$_GET['i'].'_'.$_GET['type'].'.'.$_GET['ext']);
      } else {
          //not found
      }
      ?>
      

      【讨论】:

        【解决方案4】:

        “mod_rewrite”所有尝试通过虚假路径名访问图像到 PHP 文件,图像文件名作为查询参数,然后在那里做你的魔法。将图像存储在公共文件夹之外应该可以防止任何不需要的公共访问。或者将实际图像存储在数据库本身中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-02-08
          • 1970-01-01
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多