简体   繁体   English

阻止来自直接 URL 的访问,但不阻止来自 mysql 数据库中的用户的访问

[英]Block access from direct URL, but not from users in mysql database

I have a database named users, with a table named users that contains user/pass/email for people to access my site.我有一个名为 users 的数据库,其中有一个名为 users 的表,其中包含用户/密码/电子邮件,供人们访问我的网站。 The purpose of the website is for musicians to share their music and/or recorded performances with each other.该网站的目的是让音乐家相互分享他们的音乐和/或录制的表演。 I want to restrict file access to all besides the users in my db/table.我想限制除我的 db/table 中的用户之外的所有人的文件访问。

I have the .mp3 files outside of the www directory.我有 www 目录之外的 .mp3 文件。 I'm currently using this:我目前正在使用这个:

<?php
header('Content-Type: mp3');
readfile("../Music/" . $_GET['mp3']);
?>

And to call:并调用:

<a href="music.php?mp3=songnamehere">Song name here</a>

However, if you know the direct link you can download it w/o any permissions.但是,如果您知道直接链接,则无需任何权限即可下载。

example.com/music.php?mp3=songnamehere

I have tried to combat this with .htaccess, but still accessible with direct url:我试图用 .htaccess 解决这个问题,但仍然可以通过直接 url 访问:

# secure htaccess file
<Files .htaccess>
order allow,deny
deny from all
</Files>

To no avail, I still cannot get it to work.无济于事,我仍然无法让它工作。 I need something that works with my db/table that has the users/pass/email and blocks direct url access for non users.我需要一些可以与我的 db/table 一起使用的东西,它具有用户/密码/电子邮件并阻止非用户的直接 url 访问。

Any information you can provide will be a big help.您可以提供的任何信息都会有很大帮助。 However, I'm not an expert with php so explain as much as you have the effort.但是,我不是 php 专家,所以尽你所能解释。 Thank you谢谢

I use readfile() with a hashing of a string to prevent unauthorized url access.我将readfile()与字符串散列一起使用,以防止未经授权的 url 访问。 You can use the file name and userid as part of your hashing to make sure url alone would not be sufficient.您可以使用文件名和用户 ID 作为散列的一部分,以确保仅使用 url 是不够的。 I've created a simple hashing process to give you ideas.我创建了一个简单的散列过程来为您提供想法。 Hope this helps.希望这可以帮助。

UPDATE The following code is expanded to give a full working example更新以下代码被扩展为一个完整的工作示例

<?php
  //**************************************************************************
  // the following code should be placed with your login verification code, 
  // substituting the correct userid  or username
  //**************************************************************************
  if (!isset($_SESSION)) {
      session_start();
  }
  // you will have to set the userid from 
  $_SESSION['userid'] = "user3453965";
  //**************************************************************************
?>



<?php
  //**************************************************************************
  //The following code is in a separate php from the above - e.g. music.php
  //**************************************************************************
  if (!isset($_SESSION)) {
      session_start();
  }
?>

Music File to download:<br>
<a href="<?php echo $_SERVER['PHP_SELF'] . "?file=" . urlencode("16 Bit - Twice.mp3") ?>">16 Bit - Twice.mp3</a><br>
<a href="<?php echo $_SERVER['PHP_SELF'] . "?file=" . urlencode("test.mp3") ?>">test.mp3</a><br>


<?php
  if (isset($_GET['file'])){
      // a file is chosen to download
      $file = urldecode($_GET['file']);
      if (file_exists($file)){  
        if (isset($_SESSION['userid'])){
          //****************************
          // check that the userid is valid
          //****************************
          if (valid_user($_SESSION['userid'])){
            $userid = $_SESSION['userid'];
            // generates a hash to validate the request
            $hash = gethash($file, $userid);
            downloadfile($file, $hash, $userid);
          }
        }
      }
      else{
        echo "<br>File not found: $file<br>";
      }
  }

  function valid_user($userid){
      // check that the userid if valid = e.g. call to database or however you want
      // I am using an array for this example so it can be stand alone
      $valid_users = array("henry mcmuffin", "user3453965");
      if (array_search($userid, $valid_users)){
        return true;
      }
      return false;
  }

  function gethash($string, $userid){
      // use your own method of hashing here
      // you can pass the user id and make this part of the returned string
      return md5($string . $userid);
  }


  function downloadfile($file, $hash, $userid, $outfilename=""){
      if (!isset($_SESSION)) {
          session_start();
      }

      // prevent url hacking
      // define gethash() to hash the filename
      $hash2 = gethash($file, $userid);

      // if hash correct 
      if ($hash == $hash2) {

          // File Exists?
          if (file_exists($file)){
              // Parse Info / Get Extension
              $fsize = filesize($file);
              $path_parts = pathinfo($file);
              $ext = strtolower($path_parts["extension"]);

              // Determine Content Type
              switch ($ext) {
                  case "mp3": $ctype="audio/mpeg"; break;
                  case "pdf": $ctype="application/pdf"; break;
                  case "gif": $ctype="image/gif"; break;
                  case "png": $ctype="image/png"; break;
                  case "jpeg":
                  case "jpg": $ctype="image/jpg"; break;
                  default: $ctype="application/force-download";
              }

              header("Pragma: public"); // required
              header("Expires: 0");
              header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
              header("Cache-Control: private",false); // required for certain browsers
              header("Content-Type: $ctype");

              $outfilename = ($outfilename=="" ? basename($file) : $outfilename);
              // Download file
              header('Content-Disposition: attachment; filename='.basename($outfilename));

              header("Content-Transfer-Encoding: binary");
              header("Content-Length: ".$fsize);

              if (ob_get_length() > 0 ) {
                // clear the buffer to allow download
                ob_clean();
                flush();
              }
              readfile( $file );
          } 
          else {
              echo('File Not Found: ' . $file);
          }
      }
      else {
          echo ('Invalid file request');
      }
  } 
?>

you can use sessions for this if user log in check page set same variable your login page add something like this如果用户登录检查页面设置相同的变量,您可以为此使用会话,您的登录页面添加这样的内容

<?php
session_start();
$_SESSION['login']='login';

?>

in your music.php page在您的 music.php 页面中

<?php
session_start();
if(isset($_SESSION['login'])){
header('Content-Type: mp3');
readfile("../Music/" . $_GET['mp3']);
}
else{
header('Location: login.php');

}
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM