🔑
Cloudflare R2のファイルに雑にBASIC認証を付ける
やりたいこと
- ユーザー名・パスワードを入力しないとダウンロードできないファイルを作りたい
- 1ファイルに対して複数のユーザー名・パスワードを指定できるようにしたい
- まだやってないけどKVでユーザー毎にダウンロード数をカウントしたい
- R2バケット自体のURLは隠したい
- 細かい事は気にしない
やる
- Cloudflare WorkersとHonoのBASIC認証ミドルウェア(
hono/basic-auth
)を使う - スマートにやるならKVやD1でユーザー名・パスワードを管理するのがベターだが、
面倒くさいので頻繁にデータ更新しないので今回はハードコーディングする
やった
index.ts
type Bindings = {
BUCKET: R2Bucket;
};
import { Hono } from "hono";
import { basicAuth } from "hono/basic-auth";
import { bridgeFiles } from "../resources";
const app = new Hono<{ Bindings: Bindings }>();
bridgeFiles.forEach((file) => {
app.use(`/download/${file.endpoint}`, basicAuth(...file.auth));
app.get(`/download/${file.endpoint}`, async (c) => {
const object = await c.env.BUCKET.get(file.filename);
if (object === null) {
return c.text("Not Found", 404);
}
const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set("etag", object.httpEtag);
return new Response(object.body, {
headers,
});
});
});
export default app;
別途resources.ts
にユーザー名やパスワード等を記述します。
resources.ts
import { basicAuth } from 'hono/basic-auth';
type Args = Parameters<typeof basicAuth>
export type BridgeFile = {
filename: string;
endpoint: string;
auth: Args;
}
export const bridgeFiles: BridgeFile[] = [
{
filename: "test.txt",
endpoint: "test",
auth: [
{
username: "test",
password: "test",
},
{
username: "test2",
password: "test2",
},
],
},
];
TIPS
- 今のところR2ファイルの転送時間は課金要件には関係無いので、でかいファイルを置いても問題無い。
- 実際やってみた所転送速度は3~5MByte/sくらい。速い訳では無いがこの程度なら許容範囲内。
あとがき
Cloudflareさんには頭が上がりませんわほんま
Discussion