🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
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というインフラから提供する商用サービスです。

Q&A

解決済

1回答

1547閲覧

AWS S3 で特定のパスだけ権限があるバケットに接続するには

Web_akira

総合スコア34

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というインフラから提供する商用サービスです。

0グッド

0クリップ

投稿2019/09/19 02:17

編集2019/09/19 02:18

AWS の超初心者です。

S3 に設置された CSV ファイルを PHP で定期的に取得する処理を作成する必要があります。

AWS SDK for PHP を composer でインストールしています。
勉強用に個人で作成したバケットには接続でき、
下記のスクリプトでファイル一覧が表示できました。

php

1try { 2 $s3 = new S3Client([ 3 'credentials' => [ 4 'key' => AWS_ACCESS_KEY_ID, 5 'secret' => AWS_SECRET_ACCESS_KEY, 6 ], 7 'region' => 'ap-northeast-1', 8 'version' => 'latest', 9 ]); 10 11 // バケットを指定 12 $objects = $s3->listObjects([ 13 'Bucket' => S3_BUCKET_NAME 14 ]); 15 foreach ($results as $result) { 16 foreach ($result['Contents'] as $object) { 17 echo $object['Key'] . "\n"; 18 } 19 } 20} catch (Exception $e) { 21 var_dump($e); 22}

ここからが本題です。

S3 への接続情報をお客様から頂き、AWS CLI や S3 ブラウザで一覧を取得、ダウンロードはできました。

お客様から頂いたバケット名ですが、
バケット名/jpn/hoge/ といった感じで、パス名になっています。

上記のスクリプトをお客様の接続情報に書き換えて実行すると、
403: Forbidden で、エラーコードが SignatureDoesNotMatch と表示されます。

個人的な考えですが、スクリプトは「バケット名」の指定であるのに対し、
「パス名」になっているのが問題だと思います。
また、「バケット名」、つまりパスのルートには権限がありません。
バケット名だけ指定すると、エラーコードは AccessDenied となります。

※ S3 ブラウザでも、接続はできるのですが、Failed -AccessDenied:AccessDenied と
「Tasks」タブに表示されており、ルートのパスをクリックすると AccessDenied となるので、
バケット名の直下にアクセス権限がないのは明らかです。

お聞きしたいのは、AWS SDK for PHP でパス指定して接続が出来るのか、という点です。
プログラムでアクセスする場合、パスを指定してのアクセスは無理なのでしょうか?
無理であれば、ルート直下にファイルを置いてもらえるバケットを作成できないか、
お客様に問い合わせないといけません。

ご教示のほど、よろしくお願い致します。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/09/19 03:52

SignatureDoesNotMatch 署名が間違えている だからアカウントの設定ミスじゃないのか
Web_akira

2019/09/19 04:15 編集

AWS CLI と S3 ブラウザで一覧を取得、ダウンロードはできていますので、 「パス名」にアクセスする署名は正しいのだと思います。 プログラムで接続する時に「バケット名」を指定する必要があり、 その場所の署名ではありません(与えられているのは「パス名」への接続権限だけ)。 バケット名(=ルート)の権限がないので、署名が一致しないということだと思っています。
Web_akira

2019/09/19 04:20

そもそもの疑問なのですが、プログラムでコントロールするバケットを用意する場合、 内部にディレクトリを作って、そこだけに権限を与えて使うものでしょうか? お客様も外部と連携してS3を使うのは初めてのようなので、使い方として間違っているような気もします。 バケット名を作成(=ここに署名を作る)、その中でファイルの入出力を行ったり ディレクトリの書き換えを行う、というのはしっくりきます。 バケットの中にフォルダを作成して、権限を付与するというやり方は出来ないような気がしますが、 事例としてあるのであれば教えて頂きたく思います。その方向で調べますので。
guest

回答1

0

ベストアンサー

先方が意図的に特定ディレクトリに権限を絞っている可能性もありますね。
一応ListObjectsのオプションにデリミタがあるのでそこに適切にパスを指定すれば見られるかとは思います。
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listobjects
念の為権限周りも先方に確認したほうが良いかとは思います。

もっとも、ダウンロードが目的であれば、ファイル名が決まっているのならGetObjectだけでもいいような気はしますが…。

投稿2019/09/19 04:37

yu_1985

総合スコア7588

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

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

Web_akira

2019/09/19 05:01

デリミタがあるのですね、有益な情報ありがとうございます。 指定したところ、エラーコードは相変わらず出ていますが、Access Denied に変わりました。 現在、先方に確認中です。状況が分かりましたら、また追記致します。
Web_akira

2019/09/19 05:45

ファイル名が決まっているか、ちょっとあやふやな状況なのですが、 GetObject でファイルを取得することが出来ました。 $result = $s3->getObject([ 'Bucket' => S3_BUCKET_NAME, 'Key' => "/jpn/hoge/hoge.csv" ]); 分かってしまえば簡潔なコードですね…。 ありがとうございます、本当に助かりました。 ただ、バケットの中の特定のパス内の不特定なファイル一覧、を取得する場合は このような状況では困ってしまいますね。勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問