惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Hacker News: Ask HN
Hacker News: Ask HN
N
News and Events Feed by Topic
Forbes - Security
Forbes - Security
The Last Watchdog
The Last Watchdog
TaoSecurity Blog
TaoSecurity Blog
Schneier on Security
Schneier on Security
SecWiki News
SecWiki News
V
Vulnerabilities – Threatpost
Project Zero
Project Zero
O
OpenAI News
W
WeLiveSecurity
Security Archives - TechRepublic
Security Archives - TechRepublic
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
H
Hacker News: Front Page
Cisco Talos Blog
Cisco Talos Blog
Spread Privacy
Spread Privacy
Help Net Security
Help Net Security
P
Privacy & Cybersecurity Law Blog
K
Kaspersky official blog
S
Security @ Cisco Blogs
Latest news
Latest news
AWS News Blog
AWS News Blog
U
Unit 42
Martin Fowler
Martin Fowler
阮一峰的网络日志
阮一峰的网络日志
S
Secure Thoughts
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Know Your Adversary
Know Your Adversary
Scott Helme
Scott Helme
博客园 - 司徒正美
B
Blog RSS Feed
C
Check Point Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
Docker
Google Online Security Blog
Google Online Security Blog
Jina AI
Jina AI
aimingoo的专栏
aimingoo的专栏
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Last Week in AI
Last Week in AI
月光博客
月光博客
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
SegmentFault 最新的问题
NISL@THU
NISL@THU
T
The Blog of Author Tim Ferriss
C
Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
小众软件
小众软件

mephisto.cc

修复rime-ice无法弹出候选框的问题 开机滚动字体显示优化 个人网站安全防护 树莓派上部署Vaultwarden 使用goaccess实时分析Caddy日志 个人网站监控 Hugo全站AVIF记 Linux下尝试使用Godot开发小游戏 Arch linux dae 透明代理 Airflow接管galler-dl下载任务 如何使用gallery-dl批量下载图像 Arch核显下如何愉快玩Dota2和CS2 Arch/labwc 环境网络相关设置 Rime添加dota2词库 Arch 重装记录 Supertuxkart iOS版终于发布了 打造自己的流媒体音乐服务 剪切板管理工具clipcat推荐 MangoHud性能监控 微信小程序开发记 Rofi试用 解决Arch下VSCode无法输入中文的问题 独立窗口管理器下无法录屏问题处理 上海市二手房成交数据监控 OpenLDAP监控 Arch linux如何顺畅连接蓝牙设备 使用Git和Ansible管理配置文件 Arch Linux SSL VPN 客户端配置 简单获取celery任务实时结果 Arch linux下iNode客户端的安装和使用方法 券商费率调整记 迷你主机组装记 Labwc更换定制皮肤 树莓派跑分流代理 实用自动代理配置示例 九年老鼠标复活记 Openvpn示例 Mac下如何旋转webp图片 如何隐藏Vscode中Markdown PDF插件的头部内容 解决Linux下网络配置无法变更保存的问题 labwc环境启用wlogout Ubuntu下新官方微信尝鲜 简单检测用户是否开启广告屏蔽 Atuin ZFS下卡顿问题解决 Wine安装64位微信 Fish 和 Atuin使用记 Fastapi微信公众号开发简要 Hugo根据语种展示不同内容 如何修复Waybar微信图标错误 信封加密简要 Linux环境下维护公众号记录 快速隐藏和呼出终端 Wayland环境自动切换壁纸 SuperTuxKart 试玩 简单抓取雪球股票快讯 为什么你的kill命令不能列出信号表 Wine安装微信保姆教程 Hysteria科学上网简要 Ubuntu 23.10 钉钉无法启动解决方法 网站导航栏防止插入Adsense自动广告 Linux环境按键检测 Hugo文末添加最后修改时间 Wayland环境ksnip无法复制问题解决 我眼中的股票市场 Caddy简单图片防盗链 greetd和regreet使用教程 Wayland环境下截图加后期修改 Wayland 环境下gif录屏 Firefox的一些有趣功能 Ubuntu 切换系统语言 Firefox 标题栏高度调整 网站添加回到顶部功能 Hugo自定义字体 Labwc 便捷配置 Wofi使用教程 窗口管理器labwc使用记 文件共享软件Dufs推荐 Hugo静态站点接入Adsense广告 Fcitx5配置详解 Ubuntu安装chrome的方法总结 一种Xterm.js的全屏方案 Google网址收录api Python示例 手机听离线音乐 Snipe it资产导入 应用启动器yofi使用配置 Snipe it资产管理系统安装使用 Ubuntu开机启动加速 Vue3 vite TypeScript跨域等相关设置 Ubuntu手动升级Libreoffice Ubuntu设置alacritty为默认终端 简体文章批量转换为繁体 使用Inkscape调整svg图片大小 实用命令 使用mitmproxy给手机app抓包 Python中rstrip方法细解 Github同主机多仓库部署deploy key问题处理 Linux安装最新版本Python KeePassXC使用教程 Ubuntu 22.10连接蓝牙耳机报错br-connection-profile-unavailable解决方法 Caddy日志配置轮转和格式化
Fastapi简单实现临时下载链接
2024-01-23 · via mephisto.cc

我的微信公众号提供了文件下载功能,即 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 控制时效。

为什么能工作呢,翻源码看看:

why max age work

不得不说,这还真是方便好用,好像注册服务的激活邮件也是类似原理。只不过我这里是直接返回下载链接,激活服务是继续做业务相关信息处理。

 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. 各种示例

所谓有图有真相,没错的话,发送‘芝麻开门’,返回不同的下载地址,链接十分钟内有效,应该不会有人这么无聊一直刷这个。

temporary download

假设超过了 10 分钟,会提示超时,和预期一致。

download expired

删掉 4 个字符,模拟测试错误 token 的情况,工作正常。

bad token

3. 总结

临时下载链接的功能还挺有意思的,当然还可以加下载次数限制,演员黄渤说:“ 我看就没有这个必要了吧! 防君子不防小人。”

上面是我结合网上的各种信息自己实践摸索的,编程高手可能还有更加简便的方法。

我不是高手,目前能实现出来的只能是这个样子,能解决遇到的现实问题,也希望对读者有所帮助。