Fastapi を使用した一時ダウンロードリンクの簡単な実装

私のWeChat公式アカウントは、ファイルダウンロード機能を提供しています。具体的には、Wine経由でWeChatをインストールする際に必要なファイル「InstMsiW.exe」のダウンロードパスです。前回は、ダウンロードパスがハードコードされ、「static」ディレクトリに配置されていました。ユーザーは公式WeChatアカウントのチャットを通じてダウンロードリンクを取得し、リンクは無期限に有効でした。

これは問題を引き起こします。個人ウェブサイトは帯域幅が限られており、CDNでホスティングしたくないのです。一定期間有効で期限切れになる一時的なファイルダウンロードリンクを生成する方法を見つける必要があります。これは、コストを節約しながら、実際のフォロワーのニーズに応えることができます。最近は生活が厳しいので、赤字で事業を続けることはできませんし、そのための資金もまだありません。

実装手順は以下に記載されています。

1. itsdangerous ライブラリの URLSafeTimedSerializer を使用して一時トークンを実装する

コードを以下に示します。これ以上の説明は不要です。

``python

新しいバージョンの itsdangerous では URLSafeTimedSerializer が使用されていることに注意してください。

from itsdangerous import URLSafeTimedSerializer as Serializer

from itsdangerous import BadSignature, SignatureExpired

from fastapi.responses import FileResponse

@app.get("/api/get_file/{token}") # トークンはパスパラメータ経由で渡されます。

async def get_file(token):

s = Serializer("your secret key") # 鍵です。WeChat 公式アカウント開発版のトークンを使用しています。

try:

max_age = 60 * 10 は、トークンの有効期間が10分であることを示します。この時間を超過すると、SignatureExpired が発生します。非常に重要です!

to_user = s.loads(token, max_age=60 *​​ ​​10)["to_user"]

except SignatureExpired:

logger.info("token timed out, verification failed")

return {"status": "fail", "data": "expired token(token timed out, verification failed)"} # 中国語と英語の両方の情報が提供されているのは、細心の注意が表れています😄。英語が苦手な方もいらっしゃるかもしれません。

except BadSignature:

logger.info("invalid token")

return {"status": "fail", "data": "bad token(invalid token)"}

print("to_user", to_user)

最初の部分はダウンロードするファイルへのパスで、2番目の部分は来週のファイル名です。ファイル名は非常に重要です。ファイル名がないとユーザーフレンドリーではありません。ファイル名を削除してご確認ください。

現在、ダウンロード可能なファイルは1つだけなので、ハードコードされています。

return FileResponse("api/downloads/InstMsiW.exe", filename="InstMsiW.exe")

 1
 2トークンはURLリクエストパラメータに含まれていることに注意してください。一般的に、URLで使用できる文字数は限られているためURLSafeTimedSerializerという名前が付けられています`URLSafeTimedSerializer`が読み込まれると、`max_age`によって有効期限を制御できます。
 3
 4なぜこれが機能するのでしょうか?ソースコードを見てみましょう。
 5
 6![max_ageが機能する理由](/images/why-max-age-work.webp)
 7
 8これは本当に便利で使いやすいと言わざるを得ません。登録サービスのアクティベーションメールも同様の原理で動作しているようです。ただし、ここではアクティベーションサービスがビジネス関連情報の処理を継続している間、ダウンロードリンクを直接返しています。
 9
10` ...1111"1—"1"5""""""" context""""" context"""" context""" "" ... ```python
11
12### (1 WeChat公式アカウントが開発したトークンを使用しています。
13
14token = s.dumps({"to_user": toUser}) # 一般的に、ダンプには一意の識別子が使用されます。ダンプとは簡単に言えば暗号化であり、ロードとは復号化に似ています。
15
16logger.info("ダウンロードリンクの送信を開始")
17
18print("token:", token)
19
20content = f"InstMsiw 一時ダウンロードリンク(ブラウザで開いてください。ダウンロードリンクの有効期限は10分間です): https://stock.mephisto.cc/api/get_file/{token}"
21
22replyMsg = reply.TextMsg(toUser, fromUser, content)
23
24return replyMsg.send()

2. 様々な例

諺にもあるように、「一枚の写真は千の言葉に値する」です。私の記憶が正しければ、「開けゴマ」を送信すると、10分間有効な様々なダウンロードリンクが返されます。退屈してこれを何度も更新する人はいないはずです。

一時ダウンロード

10分を超えると、予想通り有効期限切れが表示されます。

ダウンロード期限切れ

4文字を削除すると不正なトークンをシミュレートし、正常に動作します。

不正なトークン

3. まとめ

一時ダウンロードリンク機能は非常に興味深いものです。もちろん、ダウンロード制限を追加することもできます。俳優の黄渭(ホアン・ボー)は、「それは必要ないと思います! 正直な人にだけ有効で、不正な人には有効ではありません。」と述べています。

上記は、私自身の実験と様々なオンライン情報を組み合わせて導き出した結論です。プログラミングの専門家なら、もっと簡単な方法があるかもしれません。

私は専門家ではないので、今のところはこれがすべてです。それは私が直面する現実世界の問題を解決できるものであり、読者の皆様にも役立つことを願っています。

最終更新日: Friday, October 31, 2025

このシリーズの投稿:

翻訳: