こんにちは、ROBOT PAYMENTエンジニアのkanemotoです!請求管理ロボの開発を担当しています。
Webアプリケーションにおいて、ユーザーがダウンロードするファイルの管理は重要な課題の一つです。特に、請求書のような重要なドキュメントの場合、どのユーザーがどのファイルをダウンロードしたかを正確に把握することは、企業にとって信頼性と安心感を提供するために欠かせません。
このブログでは、AWSのS3を利用して、ユーザーがダウンロードするPDFファイルのスナップショットを保存する仕組みを実装した方法について解説します。この仕組みにより、ユーザーが特定の請求書をダウンロードするたびに、その請求書のスナップショットがS3に保存され、後からどのファイルがダウンロードされたかを容易に確認できるようになります。
この実装により、次のような効果が期待できます。
利用企業の安心感向上:
ユーザーがダウンロードしたファイルの履歴を正確に追跡できるため、万が一のトラブル発生時にも迅速に対応できます。
調査工数の削減と影響範囲の最小化:
問題が発生した際に、影響範囲を迅速に特定し、必要な調査工数を大幅に削減できます。
S3バケットの設定
このセクションでは、PDFスナップショットを保存するためのS3バケットの設定方法について説明します。
ここでは、保存期間の設定やアクセス権限の管理方法についても触れます。
①バケットを作成:
「バケットを作成」ボタンをクリックし、新しいバケットを作成します。バケット名とリージョンを指定します。バケット名は一意である必要があります。

参考:
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/create-bucket-overview.html
②バケットの設定:
オブジェクトの保存期間を設定します。例えば、特定の期間後に自動的に削除されるように設定することができます。
これは、S3のライフサイクルルールを使って実現できます。
S3バケット> 管理 > ライフサイクルルールを作成するから設定しましょう。

参考: https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/object-lifecycle-mgmt.html
③バケットポリシーの設定:
バケットポリシーを設定してアクセス権限を管理します。以下の例では、特定のユーザーやグループに対してバケットへのアクセスを許可します。
1. 作成したバケットを選択します
2. アクセス許可をクリックします
3. バケットポリシーにて設定します。
実装例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::your-account-id:user/your-username"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
}
]
}
参考: https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/add-bucket-policy.html
これで、S3バケットの作成と設定が完了です。次のセクションでは、実際にPDFファイルをS3にアップロードするためのPHPコードとその実行方法について説明します。
コードの実装
PHPを使用してPDFファイルをS3にアップロードするための具体的なコード例を紹介します。
①環境変数の設定
- プロジェクトのルートディレクトリに.envファイルnにて以下の内容を記述します。
ここでは、awsアクセスキーIDとシークレットアクセスキーを設定します。 また、先ほど作成したバケットネームを記入しましょう。
AWS_ACCESS_KEY_ID=your-access-key-id AWS_SECRET_ACCESS_KEY=your-secret-access-key S3_BUCKET_NAME=your-bucket-name
②スクリプトの作成:
upload_pdf.phpというファイルを作成し、以下のコードを記述します。あくまで実装例です。
<?php
require 'vendor/autoload.php';
use Aws\\S3\\S3Client;
use Aws\\Exception\\AwsException;
use Dotenv\\Dotenv;
class S3Uploader
{
private $s3Client;
private $bucketName;
public function __construct()
{
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();
$this->s3Client = new S3Client([
'version' => 'latest',
'credentials' => [
'key' => $_ENV['AWS_ACCESS_KEY_ID'],
'secret' => $_ENV['AWS_SECRET_ACCESS_KEY'],
],
]);
$this->bucketName = $_ENV['S3_BUCKET_NAME'];
}
public function uploadPdf($pdfFilePath, $userId)
{
$key = basename($pdfFilePath);
try {
$result = $this->s3Client->putObject([
'Bucket' => $this->bucketName,
'Key' => $key,
'SourceFile' => $pdfFilePath,
'ACL' => 'private',
]);
$this->logDownload($userId, $pdfFilePath, $result['ObjectURL']);
return $result['ObjectURL'];
} catch (AwsException $e) {
return "エラーが発生しました: " . $e->getMessage();
}
}
private function logDownload($userId, $pdfFilePath, $s3Url)
{
$logMessage = sprintf(
"[%s] User %s downloaded %s, saved to S3 at %s\\n",
date('Y-m-d H:i:s'),
$userId,
basename($pdfFilePath),
$s3Url
);
file_put_contents('download_log.txt', $logMessage, FILE_APPEND);
}
}
- 使用例
$uploader = new S3Uploader();
$pdfFilePath = 'path/to/your/invoice.pdf';
$userId = 'user123'; // 実際には認証システムから取得する
// ダウンロード前にPDFをアップロードしログを出力
$result = $uploader->uploadPdf($pdfFilePath, $userId);
echo "スナップショットの保存結果: " . $result . "\\n";
// ダウンロード処理 (例)
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . basename($pdfFilePath) . '"');
readfile($pdfFilePath);
このコードでは、S3Uploaderクラスを作成し、PDFファイルをS3にアップロードするメソッドを定義しています。また、使用例として、PDFファイルがダウンロードされる直前にスナップショットとしてS3にアップロードし、どのユーザーがどの請求書をダウンロードしたかを追跡するためのログを出力する方法を示しています。
まとめ
AWS S3を使用してPDFファイルのスナップショットを保存し、どのユーザーがどの請求書をダウンロードしたかを追跡する方法について説明しました。以下に、今回の実装のポイントを振り返ります。
- 実装のポイント
- AWSアカウントとS3バケットの設定:
- AWSアカウントを用意し、S3バケットを作成しました。バケットのライフサイクル管理を設定して、オブジェクトの保存期間を管理しました。
- AWSアカウントとS3バケットの設定:
- 環境変数の設定:
PHPによるS3へのアップロードメソッドの作成:
- S3Uploaderクラスを作成し、PDFファイルをS3にアップロードするメソッドを実装しました。
- アップロード成功時にそのURLを返し、エラーハンドリングも行いました。
ダウンロード前のスナップショット保存とログ出力:
- S3Uploaderクラスを作成し、PDFファイルをS3にアップロードするメソッドを実装しました。
- ユーザーがPDFをダウンロードする直前に、PDFのスナップショットをS3に保存しました。
- どのユーザーがどのPDFをダウンロードしたかをログに記録する機能を追加しました。
このように、AWS S3とPHPを活用することで、ファイル管理の精度と信頼性を向上させることができます。今後のプロジェクトにぜひ活用してみてください。
We are hiring!!
ROBOT PAYMENTでは一緒に働く仲間を募集しています!!!