代码之家  ›  专栏  ›  技术社区  ›  Constantine

fileinput上载和预览,保护文件

  •  2
  • Constantine  · 技术社区  · 8 年前

    我想知道的是如何保护这些文件不被不受限制的访问。我可以理解,如果这些文件不在公共文件夹中,那么JQuery插件将无法加载它们,但最终每个人都可以猜测链接,例如user one可以键入链接并下载其他用户的图像,有什么方法可以保护它吗?

    JQuery:

    function files(sort) {
            $.ajax({
                url: 'ajaxScripts/getFile.php',
                type: "POST",
                dataType: 'json',
                data: {sort: sort},
                async: false,
                success: function (data) {
                    var preview = [];
                    var test = [];
                    $.each(data, function (key, item) {
                        preview.push(item.RelativePath);
                        console.log(item);
                        test.push({type: item.Type, caption: item.Title + ' ' + item.ExamDate, key: item.UserExamsID, url: 'ajaxScripts/deleteFile.php', downloadUrl: item.RelativePath});
                    });
                    $("#file-input").fileinput({
                        theme: 'fa',
                        uploadUrl: 'ajaxScripts/upload.php',
                        maxFileSize: 10000,
                        overwriteInitial: false,
                        initialPreview: preview,
                        initialPreviewAsData: true,
                        initialPreviewConfig: test,
                        purifyHtml: true
    
                    });
    
                }, error: function (XMLHttpRequest, textStatus, errorThrown) {
                    console.log("XMLHttpRequest=" + XMLHttpRequest + "; textStatus=" + textStatus + "; errorThrown=" + errorThrown);
                }
            });
        }
    

    PHP: 获取文件。php

    require_once 'DBconfig.php';
    header('Content-Type: application/json');
    session_start();
    if (!isset($_SESSION['user_session'])) {
        header("Location: /index.html");
        die();
    }
    $sort = $_POST['sort'];
    $userID = $_SESSION['user_session'];
    
    
    try {
        $stmt = $db_con->prepare("SELECT `RelativePath`,`Title`,`ExamDate`, `UserExamsID`, `Type` FROM `userexams` WHERE `UserID`=:userid AND UserExamsID>21 ORDER BY `ExamDate` ASC");
        $stmt->bindParam(':userid', $userID, PDO::PARAM_INT);
        $stmt->execute();
        $res = $stmt->fetchAll(PDO::FETCH_ASSOC);
        echo json_encode($res);
    } catch (PDOException $e) {
        echo $e->getMessage();
    }
    

    并上传。php 我不会发布代码,但它基本上是在web根文件夹so/uploads/{userid}中创建一个以userid为名称的文件夹,并以其原始名称+一个随机字符串存储文件,以避免同名文件冲突,然后写入数据库的路径,以及原始文件名和它所属的用户id。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Matt S    7 年前

    将上传的文件存储在webroot之外,并在检查用户是否有访问权限后使用PHP将其返回。例如:

    // Let the browser know to expect a binary file
    header('Content-Type: application/octet-stream');
    session_start();
    if (!isset($_SESSION['user_session'])) {
        // Block access for users not logged in
        header("HTTP/1.0 403 Forbidden");
        die();
    }
    $userID = $_SESSION['user_session'];
    
    $path = $_GET['path'];
    // Check the logged in user is requesting one of their own files
    // (Probably want something more elaborate; this is just an example)
    if (strpos($path, '/uploads/' . $userID . '/') === false) {
        header("HTTP/1.0 403 Forbidden");
        die();
    }
    
    // Security check the request is valid (again, just one example)
    if (strpos($path, '..') !== false) {
        header("HTTP/1.0 403 Forbidden");
        die();
    }
    
    // Return the image
    readfile('/path/to/uploads' . $path);
    

    无论您想从客户端请求图像,都可以使用路径作为参数调用此脚本。如果要以内联方式显示图像,则需要确定正确的MIME类型并在内容类型标题中进行设置。