v2での作り方は転がってるが、v3での作り方がわからず若干ハマったのでメモ
パッケージインストール
yarn add @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
環境
>yarn list --pattern @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
yarn list v1.22.19
warning Filtering by arguments is deprecated. Please use the pattern option instead.
├─ @aws-sdk/[email protected]
└─ @aws-sdk/[email protected]
Done in 1.13s
対応
BackBlazeB2の keyID をアクセスキーに、applicationKey をシークレットアクセスキーに、バケットのEndpointをエンドポイントに設定して作成する
以下作成したコード
/main.ts
import Client from "./BucketClinet";
const client = new Client(accessKey, secretAccessKey, endpoint);
url = await client.getPreSignedUrl(env.BUCKET_NAME, "public/sample.png");
BucketClient.ts
import { S3Client, S3ClientConfig, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
export default class BucketClient {
private s3ClientConfig: S3ClientConfig;
constructor(
private accessKey: string,
private secretAccessKey: string,
private endpoint: string
) {
this.s3ClientConfig = {
endpoint: { hostname: this.endpoint, protocol: "https", path: "/" },
// 未指定の場合PreSignedUrlにホスト名が含まれない
forcePathStyle: true,
// 未指定の場合エラーになるため指定
region: "ap-northeast-1",
credentials: {
accessKeyId: this.accessKey,
secretAccessKey: this.secretAccessKey,
},
};
}
public async getPreSignedUrl(
bucket: string,
key: string,
expiresIn: number = 3600
) {
const bucketParams = {
Bucket: bucket,
Key: key,
};
const s3Client: S3Client = new S3Client(this.s3ClientConfig);
const command = new PutObjectCommand(bucketParams);
return getSignedUrl(s3Client, command, {
expiresIn: expiresIn,
});
}
}
- Note
S3ClientConfigの region はカスタムエンドポイントを使用する場合でも指定しないとエラーになる
S3ClientConfigの forcePathStyle を指定しないとpresigned URLのエンドポイント部分が空になる
確認
vscodeのRestClientで確認
presigned.http
PUT ${PRESIGNED_URL}
content-type: image/png
< ./sample.png