web-dev-qa-db-ja.com

Rest apiでjsonエンコーディングをオーバーライドする

安全なダウンロードプラグインを作成しようとしています。

私は残りのapiがこのタスクのための最良の選択肢であることを見つけました、しかし私はContent-Type:のようなヘッダーを変えることができません。 register_rest_routeコールバックでは、これらのヘッダはすでに設定されています。 Content-disposition: attachment, filename=asd.txtを設定すると、ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITIONがクロムで表示されます。

私は残りがこれらのタスクを処理することを意味していないことを知っています、しかし私は少しも選択肢を見つけることができませんでした。もしあれば、plsはそれについて教えてください。

ダウンロードされたデータはjsonでエンコードされているようです。

私はワードプレスの「魔法」にうんざりしています。これらのタスクは、単純なPHPを使用すると非常に簡単になりますが、wordpressでは単純に複雑になります。

誰かがこれらのマジックヘッダを無効にする方法を教えてください***私のプラグインでセキュリティで保護された(php)ダウンロードの方法をお勧めします。

(いいえ、私はサードパーティのプラグインを使用したくありません。私はそれらの多くを試してみました。これらのどれも今のところうまくいきませんでした...:D

これが私の 実験的な codeです。

add_action('rest_api_init', function() {
    register_rest_route('secure-downloads/v1', '/download/(?P<filename>.*)', 
    array(
        'methods' => 'GET',
        'callback' => 'secure_downloads_handle_download'
    ));
});
function secure_downloads_handle_download(WP_REST_Request $request)
{
    $filename = urldecode($request->offsetGet('filename'));
    if(strpos($filename, '/..'))
    {
        return new WP_REST_Response('', 403);
    }
    $path = SECURE_DOWNLOADS_UPLOAD_DIR . $filename;
    return new WP_REST_Response(file_get_contents($path), 200, array(
        'Content-Type' => 'application/octet-stream',
        'Content-Transfer-Encoding' => 'Binary',
        'Content-disposition' => 'attachment, filename=\\' . $filename . '\\'
    ));
}
2
Jumi

これが私が見つけたものです:

ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITIONエラーはContent-Dispositionヘッダーの悪い構成でした。これは正しいものです:

array(
    'Content-Disposition' => 'attachment; filename="' . $filename . '"'
)

@Tom J Nowellが指摘したように、添付後の セミコロン 、ファイル名の前後の 二重引用符 、および 大文字のD に注意してください。

これでヘッダの問題は解決されましたが、WP_REST_Responseはまだjsonでエンコードされたようにファイルを出力します。だから私は従来の方法を取った:

header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Type: application/octet-stream');
readfile($path);
exit;
0
Jumi

Content dispositionフィールドを追加すれば十分です。

しかし具体的にはContent - d ispositionではなくContent - _ d _ ispositionです。

それが存在し有効であることを確認するために、file_get_contentsに渡されるファイル名パラメータに検証を追加します。そうでなければ、ディレクトリトラバーサル攻撃やリモートURLリクエストに対して脆弱になる可能性があります。

1
Tom J Nowell