【问题标题】:Problems with security policy for Filepicker Convert?Filepicker Convert 的安全策略有问题吗?
【发布时间】:2013-10-03 17:01:29
【问题描述】:

我使用 Filepicker 从客户的计算机“读取”然后“存储”图像。现在我想使用 Filepicker 调整图像大小,但总是出现 403 错误:

POST https://www.filepicker.io/api/file/w11b6aScR1WRXKFbcXON/convert?_cacheBust=1380818787693 403 (FORBIDDEN) 

我对“read”、“store”和“convert”调用使用相同的安全策略和签名。这是错的吗?因为当调用“read”和“store”时,还没有文件句柄(例如 InkBlob.url 中的最后一个字符串部分)。但似乎必须使用“存储”InkBlob 返回的文件句柄生成“转换”策略/签名?如果是这种情况,在javascript中更方便的方法是什么?因为在“转换”中,除非我为此编写 API 调用,否则我无法访问生成安全策略的 Python 函数。

我的代码 sn-p 如下(initialFpSecurityObj 是在 Python 中使用空句柄预先生成的):

filepicker.store(thumbFile, {
    policy: initialFpSecurityObj.policy, 
    signature: initialFpSecurityObj.signature,
    location: "S3",
    path: 'thumbs/' + initialFpSecurityObj.uniqueName + '/',
},function(InkBlob){
    console.log("Store successful:", JSON.stringify(InkBlob));
    processThumb(InkBlob);
}, function(FPError){
    console.error(FPError.toString());
});

var processThumb = function(InkBlob){
    filepicker.convert(InkBlob, {
        width: 800,
        height: 600,
        format: "jpg",
        policy: initialFpSecurityObj.policy, 
        signature: initialFpSecurityObj.signature,
    }, function(InkBlob){
        console.log("thumbnail converted and stored at:", InkBlob);
    }, function(FPError){
        console.error(FPError);
    };
}

非常感谢您的帮助。

--- 编辑 ---

下面是生成initialFpSecurityObj的Python代码的sn-p

def generateFpSecurityOptions(handle, userId, policyLife=DEFAULT_POLICY_LIFE):
    expiry = int(time() + policyLife)
    json_policy = json.dumps({'handle': handle, 'expiry': expiry})
    policy = base64.urlsafe_b64encode(json_policy)

    secret = 'XXXXXXXXXXXXXX'
    signature = hmac.new(secret, policy, hashlib.sha256).hexdigest()

    uniqueName = hashlib.md5()
    uniqueName.update(signature + repr(time()))
    uniqueName = uniqueName.hexdigest() + str(userId)

    return {'policy':policy, 'signature':signature, 'expiry':expiry, 'uniqueName':uniqueName}

fp_security_options = generateFpSecurityOptions(None, request.user.id)

然后在django模板中检索fp_security_options:

var initialFpSecurityObj = {{fp_security_options|as_json|safe}};

生成 fp_security_options 的方式对我(前同事的代码)来说是可疑的,因为句柄是 None。

【问题讨论】:

  • 您使用的 json 策略对象是什么?
  • 非常感谢您的回复!我已编辑问题以包含生成 json 策略的 Python 代码。

标签: filepicker.io


【解决方案1】:

我的建议是创建两个策略:一个是句柄绑定的并允许存储文件,另一个不是句柄绑定的转换。在这种情况下,假设您没有指定句柄,您可以设置更短的到期时间以提高安全级别。

【讨论】:

  • 谢谢brettcvz。这就是我一直在寻找的答案。我最终分别使用了两种策略来存储/挑选和转换。虽然你好像说反了。存储文件不需要句柄,因为 FilePicker 尚不存在该文件。转换文件需要从“store”调用返回的 InkBlob 对象的“url”属性中提取的句柄。我已经证明这是有效的。
【解决方案2】:

您的问题可能是您的政策不包含任何“呼叫”规范。我建议:

json_policy = json.dumps({'handle': handle, 'expiry': expiry, 'call':['pick','store','read','convert']})

但正如我们的(非常忙;)brettcvz 建议的那样,仅用于转换,这已经足够了:

json_policy = json.dumps({'handle': handle, 'expiry': expiry, 'call':'convert'})

您可以在安全文档https://developers.inkfilepicker.com/docs/security/中找到它

如果您仍有问题,请使用 REST 调用,它是免费的。以下方法是 JavaScript 并返回一个 url 到文件选择器的 REST 端点,可用于检索转换后的图像。 _options 对象如下所示

var myOptions = {
    w: 150,
    h: 150,
    fit: "crop",
    align: "faces",
    format: "jpg",
    quality: 86
};

并且将使用文件选择器 REST-API 指定的所有参数(查看 https://developers.inkfilepicker.com/docs/web/#inkblob-images)。

function getConvertedURL(_handle, _options, _policy, _signature) {
    // basic url piece
    var url = "https://www.filepicker.io/api/file/" + _handle + "/convert?";
    // appending options
    for (var option in _options) {
        if (_options.hasOwnProperty(option)) {
            url += option + "=" + _options[option] + "&";
        }
    }
    // appending signed policy
    url += "signature=" + _signature + "&policy=" + _policy;
    return url;
}

【讨论】:

  • 非常感谢 Moritz 提供的代码 sn-p!原来“电话”不是我遇到的问题。我的问题是我需要使用 InkBlob 文件的唯一“句柄”来提供“转换”调用,以便通过安全检查。这是有道理的,因为它可以防止用户弄乱其他人的上传。无论如何,感谢您的宝贵时间!
  • 非常欢迎您,对我来说,您的json_policy=... 中的句柄似乎已经到位。问候
【解决方案3】:

所以我终于自己想通了,虽然后来我看到了 brettcvz 的建议。关键是要让 'convert' 工作,我必须指定上传文件的确切句柄(即从 'store' 或 'pickAndStore' 调用返回的 InkBlob 的 url 属性中字符串的最后一位。

我做的第一件事是编辑生成安全策略和签名的 Python 函数:

def generateFpSecurityOptions(handle, userId, policyLife=DEFAULT_POLICY_LIFE):
    expiry = int(time() + policyLife)
    json_policy = json.dumps({'handle': handle, 'expiry': expiry})
    policy = base64.urlsafe_b64encode(json_policy)

    secret = 'XXXXXXXXXXXXXX'
    signature = hmac.new(secret, policy, hashlib.sha256).hexdigest()

    if not handle == None:
        uniqueName = handle
    else:
        uniqueName = hashlib.md5()
        uniqueName.update(signature + repr(time()))
        uniqueName = uniqueName.hexdigest() + str(userId)

    return {'policy':policy, 'signature':signature, 'expiry':expiry, 'uniqueName':uniqueName}

fp_security_options = generateFpSecurityOptions(None, request.user.id)

然后我必须在我们的 Django 框架中建立 API 调用,以通过 AJAX 动态获取此安全策略对象。我很幸运,我的同事以前写过它。所以我只是在 Javascript 中调用 API 函数来检索文件特定的安全策略对象:

var initialFpSecurityObj = {{fp_security_options|as_json|safe}};
filepicker.store(thumbFile, {
    policy: initialFpSecurityObj.policy, 
    signature: initialFpSecurityObj.signature,
    access: "public"
}, function(InkBlob) {
    processThumb(InkBlob);
}, function(FPError) {
    console.error(FPError.toString());
}, function(progress) {
    console.log("Loading: " + progress + "%");
});

var processThumb = function(InkBlob) {
    var fpHandle = InkBlob.url.split('/').pop();
    $.ajax({
        url: API_BASE + 'file_picker_policy',
        type: 'GET',
        data: {
            'filename': fpHandle
        },
        dataType: 'json',
        success: function(data) {
            var newFpSecurityObj = data.data;
        filepicker.convert(InkBlob, {
            width: 800,
            height: 600,
            format: "jpg",
            policy: newFpSecurityObj.policy, 
            signature: newFpSecurityObj.signature,
        }, {
            location: "S3",
            path: THUMB_FOLDER + '/' + newFpSecurityObj.uniqueName + '/', 
        }, function(fp) { // onSuccess
            console.log("successfully converted and stored!");
            // do what you want with the converted file
        }, function(FPError) { // onError
            console.error(FPError);
        }); 
        },
        failure: function() {
        alert("There was an error converting the thumbnail! Please try again.");
        }
    });

};

【讨论】:

    猜你喜欢
    • 2021-01-11
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 2016-04-20
    • 2013-12-23
    • 2021-06-26
    相关资源
    最近更新 更多