質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Amazon CloudFront

Amazon CloudFrontは、AWSの高速且つ高パフォーマンスなコンテンツ配信(CDN) サービス。容量の大きいコンテンツをキャッシュさせてWebサーバの負荷を軽減し、サーバダウンの防止など安定した配信が可能になります。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

1回答

4905閲覧

【CloudFront】【PHP】署名URL発行時に独自のファイル名を指定したい

hasshy

総合スコア102

Amazon CloudFront

Amazon CloudFrontは、AWSの高速且つ高パフォーマンスなコンテンツ配信(CDN) サービス。容量の大きいコンテンツをキャッシュさせてWebサーバの負荷を軽減し、サーバダウンの防止など安定した配信が可能になります。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Amazon S3

Amazon S3 (Simple Storage Service)とはアマゾン・ウェブ・サービスが提供するオンラインストレージサービスです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

2クリップ

投稿2020/02/14 19:41

編集2020/02/16 05:17

ファイルアップローダーのような仕組みのシステムを作っています。
アップローダーと一緒に、ダウンロード用のURLを発行する機能も実装しているのですが、想定した挙動をしません。

具体的には目的ごとに2つのファイル名があり、ダウンロードされたファイルは後者のファイル名にしたいです。

  • ストレージにアップロードするファイル名(重複しないランダム文字列)
  • ダウンロード用のファイル名(日本語)

S3から署名URLを発行していた時は実装できていました。
CloudFront経由で署名URLで発行するように調整したところ、ダウンロードしたファイル名を変更できなくなりました。

CloudFrontでファイル名を指定する方法は無いでしょうか?

システムの概要

S3バケットにファイルをアップロードします。
ダウンロードしたいユーザーには、別途ダウンロードURLを通知します。
通知に記載されたダウンロードURLを経由して、S3からファイルをダウンロードします。

イメージ説明

以前までの仕様と変更した経緯

元はS3の署名URL機能でダウンロードリンクを作成していました。
laravelで開発していますので、下記の様に実装できていました。

php

1$disk = Storage::disk(env('STORAGE_TYPE', 's3')); 2return $disk->temporaryUrl( 3 'upload/abcdefghi.pdf', 4 now()->addDay(1), 5 [ 6 'ResponseContentDisposition' => 'attachment; filename=' . rawurlencode('ファイル名.pdf') 7 ] 8);

しかし、生成されたリンクがNotFound(404)やForbidden(403)の場合、XMLがパースされたエラーページになってしまいます。
パースされた情報だと、ユーザーに状況が伝わらないため、CloudFrontのエラー出し訳をすることにしました。

状況

CloudFront経由してダウンロードURLの生成、URLからファイルの取得はできます。
エラーは発生していない様です。

ファイル名の指定と、(本件とは別ですが)ファイルのダウンロードが出来ません。(ブラウザで表示されてしまいます。)

後述しますが、response-content-disposition=attached; filename=(ファイル名)を記述してもそもそも、効いていない(パラメータの解析?)がされていないように思います。

環境

アプリケーション

下記の環境で実装しています

環境名バージョン
php7.3.13
aws-sdk-php3.109
laravel5.8.*

処理

S3については前述した通りです。
CloudFrontについては下記の様な処理を書いています。

php

1use Aws\CloudFront\CloudFrontClient; 2use Aws\Exception\AwsException; 3 4public function getCloudFrontDownloadUrl() { 5 $client = new CloudFrontClient([ 6 'profile' => 'default', 7 'region' => env('AWS_DEFAULT_REGION', 'ap-northeast-1'), 8 'version' => 'latest' 9 ]); 10 11 // 有効期限 12 $expires = time() + 24 * 60 * 60; 13 14 // URL設定 15 $cloudFrontDomain = 'https://xxxxxxx.cloudfront.net/'; 16 $url = $cloudFrontDomain 17 . 'upload/abcdefghi.pdf' 18 . "?response-content-disposition=attachment; filename=" . rawurlencode('ファイル名.pdf'); 19 20 return $client->getSignedUrl([ 21 'url' => $url, 22 'expires' => $expires, 23 'private_key' => '(プライベートキーファイル.pem)', 24 'key_pair_id' => '(アクセスキーID)' 25 ]); 26}

ファイル名の指定は下記の処理を、URLのパラメータとして追加する事で対応できると考えていました。

response-content-disposition=attachment; filename=(ファイル名)

公式ドキュメントでは確認できなかったのですが、CloudFrontの署名URL実装方法を見ていると下記の様な指定方法をしていたのでこの方法を取りました。

サーバー

AWSで構築しています。
CloudFront、S3で特筆すべき設定は下記です。

CloudFrontの設定

CloudFrontとS3を連携しますので、デフォルトの状態から下記の設定を変更しています。
それ以外は、デフォルトの設定のままです。

設定名設定値
Origin Domain Nametest_bucket.s3.amazonaws.com
Restrict Bucket Accessyes
Grant Read Permissions on BucketYes, Update Bucket Policy

S3の設定

前項でポリシーをアップデートしていますので下記の様な構成になっています。

{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ***" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::test_bucket/*" } ] }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

CloudFront(Behaviors)の設定

  • 署名URLの利用の設定をします。
  • Query Stringでresponse-content-dispositionの利用の許可をします。

Distributionsから対象のDistributionを選び
BehaviorsタブからEdit

設定名設定値
Query String Forwarding and CachingForward all, cache based on whitelist
Query String Whitelistresponse-content-disposition
Restrict Viewer AccessYes
Trusted SignersSelf

処理の変更

  • URLを作成する部分はファイル名をURLエンコードした上で、全体をもう一度URLエンコードします。

PHP

1$filename = rawurlencode('ファイル名.pdf'); 2$disposition = rawurlencode('attachment; filename=' . $filename); 3$url = $cloudFrontDomain. 'upload/abcdefghi.pdf?response-content-disposition=' . $disposition;

上記でいかがでしょうか?

投稿2020/02/18 11:05

mor337

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問