1

Filepicker を使用して、クライアントのコンピューターからイメージを「読み取り」、「保存」します。Filepicker を使用して画像のサイズを変更したいのですが、常に 403 エラーが発生します。

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

「read」、「store」、「convert」の呼び出しに同じセキュリティ ポリシーと署名を使用しています。これは間違っていますか?"read" と "store" が呼び出されたとき、まだファイル ハンドルがないためです (たとえば、InkBlob.url の最後の文字列部分)。しかし、「保存」インクブロブで返されたファイルハンドルを使用して「変換」ポリシー/署名を生成する必要があるようですか? この場合、javascript で行うより便利な方法は何ですか? 「変換」では、セキュリティ ポリシーを生成する Python 関数には、そのための API 呼び出しを作成しない限りアクセスできないためです。

以下のコード スニペット (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 コードのスニペットです。

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 であるため、私 (元同僚のコード) には疑わしいです。

4

3 に答える 3

0

問題はおそらく、ポリシーに「呼び出し」仕様が含まれていないことです。私は提案します:

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 であり、変換された画像を取得するために使用できる filepicker の REST エンドポイントに URL を返します。_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;
}
于 2013-10-09T09:09:25.457 に答える
0

私が推奨するのは、2 つのポリシーを作成することです。1 つはハンドルにバインドされ、ファイルの保存を許可し、もう 1 つはハンドルにバインドされていない変換用です。この場合、ハンドルを指定していなければ、有効期限を短く設定してセキュリティのレベルを上げることができます。

于 2013-10-09T02:42:38.397 に答える
0

それで、後で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.");
        }
    });

};
于 2013-10-11T13:46:58.253 に答える