PresignedURLを使用してデバイスにファイルを配信する

AWS SDK for JavaScript v3を使用して、PUT用およびGET用のPresigned URLを発行する方法について書きました。
2023.02.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。CX事業本部Delivery部サーバーサイドチームの木村です。

概要

システムの管理者等がデバイスへ向けて、設定ファイルやファームウェアなどを送りたい場合があると思います。

などさまざまな方法が考えられます。

今回はPresigned URLを使用した方法について書かせていただきます。 AWS SDK for JavaScript v3を使用します。

Presigned URLについて

ドキュメントによると、

署名付き URL を使用して、オプションでオブジェクトを共有したり、顧客/ユーザーが AWS セキュリティ認証情報またはアクセス許可なしでオブジェクトをバケットにアップロードしたりできます。

URL を共有でき、URL へのアクセス権を持つユーザーは、URL に埋め込まれたアクションを、元の署名ユーザーであるかのように実行できます。

専用のURLを使用して、AWSの認証情報を持たないユーザーがオブジェクトをアップロードやダウンロードできる仕組みです。

1. 大まかな流れ

2. PUT用Presigned URLを取得

AWS SDK for JavaScript v3の以下のモジュールを使用します。

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/index.html#aws-sdkclient-s3 https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_s3_request_presigner.html

Lambdaにおけるコード例は以下の通りです。

import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import {
  S3Client,
  PutObjectCommand,
  PutObjectCommandInput,
} from "@aws-sdk/client-s3";
const client = new S3Client({
  region: "ap-northeast-1",
});
const params: PutObjectCommandInput = {
  Bucket: "<S3Bucket名>",
  Key: "key/to/file",
};

const handler = async () => {
  const command = new PutObjectCommand(params);
  const url = await getSignedUrl(client, command, { expiresIn: 3600 });
  return url;
};

3. ファイルをアップロード

Axiosの場合は以下のようなスクリプトになります。 アップロード対象のファイル名は仮にtest.txtとします。

import Axios from "axios";
import * as fs from "fs";

const handler = async () => {
  const url = "2.で取得したURL";

  const file = fs.readFileSync("test.txt");
  Axios.put(url, file);
};

handler().then((res) => {
  console.log(res);
});

curlの場合は以下のようにアップロードできます。

$ export url="2.で取得したURL"
$ curl -X PUT --upload-file test.txt $url

4. Get用Presigned URLを取得

2.のスクリプトとほぼ同じです。 GetObjectCommand, GetObjectCommandInputに置き換えます。

import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import {
  S3Client,
  GetObjectCommand,
  GetObjectCommandInput,
} from "@aws-sdk/client-s3";
const client = new S3Client({
  region: "ap-northeast-1",
});
const params: GetObjectCommandInput = {
  Bucket: "<S3Bucket名>",
  Key: "key/to/file", // ※
};

const handler = async () => {
  const command = new GetObjectCommand(params);
  const url = await getSignedUrl(client, command, { expiresIn: 3600 });
  return url;
};

※ 存在しないKeyを指定してもPresigned URLは発行されますが、ダウンロードする際にエラーになります。

5. ファイルをダウンロード

curlを使用した場合は以下のような方法になります。デバイス側の実装に合わせて任意の方法を選択してください。

$ export url="2.で取得し、事前に伝達されたURL"
$ curl $url > <保存先>

※ Presigend URL発行後に、対象のオブジェクトを変更した場合でも、ダウンロードしたファイルに変更が反映されます。

6. 最後に

以上、Presigned URLを使用したファイル配信の方法を記載しました。

どなたかのお役に立てたら幸いです。