Fastapi简单实现临时下载链接
我的微信公众号提供了文件下载功能,即 wine 安装微信时需要的一个文件InstMsiW.exe
。上次是写死路径放在 static 目录上,用户通过公众号对话获取链接下载,链接一直有效。
这样就会存在一个问题,个人网站带宽有限,也不想放到 cdn 上面,得想个办法生成一个临时文件下载链接,在一段时间内有效,一段时间后过期,既服务了真实粉丝,也能节约成本,这年头生活已经够艰难了,不能做亏本生意,还没那个实力。
下面记录实现过程:
1. 使用 itsdangerous 库的 URLSafeTimedSerializer 实现临时 token
直接上代码不啰唆
1# 注意新版本 itsdangerous 是 URLSafeTimedSerializer
2from itsdangerous import URLSafeTimedSerializer as Serializer
3from itsdangerous import BadSignature, SignatureExpired
4from fastapi.responses import FileResponse
5
6@app.get("/api/get_file/{token}") # token 通过 path parameter 传递
7async def get_file(token):
8 s = Serializer("your secret key") # 你的key,你应该懂的,我直接用的公众号开发的那个token
9 try:
10 # max_age = 60 * 10 标识token十分钟内有效,超过就会触发 SignatureExpired, 很关键!!!
11 to_user = s.loads(token, max_age=60 * 10)["to_user"]
12 except SignatureExpired:
13 logger.info("token超时,验证失败")
14 return {"status": "fail", "data": "expired token(token超时,验证失败)"} # 中英文信息都提供,用心良苦😄,真的有可能有读者英文不好的
15 except BadSignature:
16 logger.info("无效token")
17 return {"status": "fail", "data": "bad token(无效token)"}
18 print("to_user", to_user)
19 # 前面是待下载文件路径,后面是下周后的文件名,filename很关键,不然不够友好,不信你去掉试试看
20 # 目前只提供一个文件下载,所以是写死的
21 return FileResponse("api/downloads/InstMsiW.exe", filename="InstMsiW.exe")
注意 token 在 URL 请求参数中,一般来说 URL 中能合法使用的字符是有限的,所以才叫 URLSafeTimedSerializer,URLSafeTimedSerializer
loads 时能通过 max_age 控制时效。
为什么能工作呢,翻源码看看:
不得不说,这还真是方便好用,好像注册服务的激活邮件也是类似原理。只不过我这里是直接返回下载链接,激活服务是继续做业务相关信息处理。
1### 此处省略 一万行代码 ###
2# 意思公众号用户发送‘芝麻开门’,就回复一个临时下载地址给用户使用
3if Content == "芝麻开门":
4 s = Serializer("your secret key") # 你的key,你应该懂的,我直接用的公众号开发的那个token
5 token = s.dumps({"to_user": toUser}) # 一般用一个唯一标志进行dumps,dumps可以简单理解为加密,loads类比为解密
6 logger.info("开始发送下载链接")
7 print("token:", token)
8 content = f"InstMsiw临时下载地址(请使用浏览器打开,10分钟内下载链接有效): https://stock.mephisto.cc/api/get_file/{token}"
9 replyMsg = reply.TextMsg(toUser, fromUser, content)
10 return replyMsg.send()
2. 各种示例
所谓有图有真相,没错的话,发送‘芝麻开门’,返回不同的下载地址,链接十分钟内有效,应该不会有人这么无聊一直刷这个。
假设超过了 10 分钟,会提示超时,和预期一致。
删掉 4 个字符,模拟测试错误 token 的情况,工作正常。
3. 总结
临时下载链接的功能还挺有意思的,当然还可以加下载次数限制,演员黄渤说:“ 我看就没有这个必要了吧! 防君子不防小人。”
上面是我结合网上的各种信息自己实践摸索的,编程高手可能还有更加简便的方法。
我不是高手,目前能实现出来的只能是这个样子,能解决遇到的现实问题,也希望对读者有所帮助。
最后修改于: Tuesday, January 30, 2024
版权申明:
- 未标注来源的内容全部为原创,未经授权请勿转载(因转载后排版往往错乱、内容不可控、无法持续更新等);
- 非营利为目的,演绎本博客任何内容,请以'原文出处'或者'参考链接'等方式给出本站相关网页地址(方便读者)。