Getting private files or showing private images in a HTML page

后端 未结 2 1519
野趣味
野趣味 2020-12-06 14:52

I wonder how to publishing private user files but in the way only that user can access it. I mean, after logging in, there would be many files that only the

2条回答
  •  旧时难觅i
    2020-12-06 15:19

    Alright. Since I'm unformilliar with your code, I'm going to use a bit of general code as an example. All you have to do is adjust it.

    First a very basic html that will upload the video / mp3 / image or whatever:

    Select the file to upload:

    Next you need to prepare your database table:

    CREATE TABLE `uploads` (
        `id` INT(11) NOT NULL AUTO_INCREMENT,
        `userid` INT(11) NOT NULL,
        `name` VARCHAR(64) NOT NULL,
        `original_name` VARCHAR(64) NOT NULL,
        `mime_type` VARCHAR(20) NOT NULL,
        PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
    

    Now comes the file upload part. At this point I should mention that I'm not very well formilliar with MySQLi. Therefor I'm using PDO in this example. You should however be able to adjust it to MySQLi if you prefer:

    query("INSERT INTO uploads SET userid=:id, name=:filename, original_name=:oriname, mime_type=:mime");
    
            $db->bind(":userid",$_SESSION['your_login_userid_here']);
            $db->bind(":filename",basename($uploadfile));
            $db->bind(":oriname",basename($_FILES['userfile']['name']));
            $db->bind(":mime",$_FILES['userfile']['type']);
    
            try {
                $db->execute();
            } catch (PDOException $e) {
                unlink($uploadfile);
    
                die("Error saving data to the database. The file was not uploaded");
            }
    
            $id = $db->lastInsertId();
            echo "File succesfully uploaded.\n";
    
        } else {
            echo "File uploading failed.\n";
        }
    } else {
        # No upload received. Send user to upload page
        Header("Location: html_upload_form.html");
    }
    
    ?>
    

    So what is happening? Basicly we are uploading the file to our upload dir where we give it a random filename with the .tmp extension. In our database we're saving this random filename, the original filename, and what type of file it is. Ofcourse we're adding the userid as well so we know to whom to file belongs. The benefits of this approach are as follows:

    • - No one will ever know the file name on the server.
    • - No one will ever know the original file name except the owner.
    • - The Mime Type allows us to setup our HTML5 mediaplayer.
    • - The owner is able to download the file, but no one else.

    Up comes the PHP file that will retrieve the uploaded file for us:

    query('SELECT userid, name, mime_type FROM uploads WHERE id=:id');
    
    $db->bind(":id", $id);
    
    try {
        $file = $db->single();
    } catch (PDOException $e) {
        die("Error fetching data from the database");
    }
    
    # Check if file belongs to user
    if($_SESSION['your_login_session_here'] != $file['userid']){
        die("This file does not belong to you!");
    }
    
    if(is_null($file) || count($file)==0) {
        die("File not found");
    }
    
    $newfile = $file['original_name']; # The original filename
    
    # Send headers and file back
    header('Content-Description: File Transfer');
    header('Content-Disposition: attachment; filename='.basename($newfile));
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($uploaddir.$file['name']));
    header("Content-Type: " . $file['mime_type']);
    readfile($uploaddir.$file['name']);
    
    ?>
    

    What is happening? In this file, you're using the file id to retrieve the users file from the database. That way no user needs to know any filename at all! Thanks to our headers, the owner of the file will however be able to download the file with it's original name, without knowing the filename on the server at all.

    So next I will give you a short example on how to show the user all his files:

    query("SELECT id, original_name, mime_type FROM uploads WHERE userid=:id");
    
    $db->bind(":id",$_SESSION['your_login_session_here']);
    
    try {
        $files = $db->resultset();
    } catch (PDOException $e) {
        die("Error fetching data from the database");
    }
    
    if($db->rowCount() > 0){
        foreach($files as $file){
            echo "". $file['original_name'] ."
    "; } } else { echo "No files found!"; } ?>

    And finally comes the PHP file that will display the file in some HTML mediaplayer. I will only 2 examples here, you should be able add your own very easily:

    
    
        
    
    
    
        
    
    
    

    Now to make sure no one is going to just brute force attack your uploads folder, you need to create a .htaccess file inside this folder. The following code will block anyone from accessing that folder except the server itself ofcourse:

    order deny,allow
    deny from all
    allow from 127.0.0.1
    

    My PDO Class.

提交回复
热议问题