先看数据模型。
查看链接: /n/{slug}
编辑链接: /e/{32字节随机数}
一个笔记本,两个 URL。一个给人看,一个证明你是主人。没有注册,没有登录,没有 users 表。编辑令牌是 32 字节随机数,只在创建时显示一次,库里存的是 SHA-256 哈希。
这是 SharePad,介于 pastebin 和 wiki 之间的一个东西——不注册就能建多页 Markdown 笔记本,发链接给人看。作者 Varshith V Hegde,2025 年 8 月发在 dev.to 上,代码开源,clone 下来就能自己部署。
我不打算聊这个工具本身。我想聊的是这个认证模型。它可能是我在这种小工具里见过的最诚实的认证设计。
诚实在哪
多数小工具的认证只有两条路。要么硬上一个完整用户系统——邮箱、密码哈希、session、找回密码、OAuth 三件套——为了一个用户一辈子可能只用三次的页面。要么干脆不做,谁拿到 URL 谁就能改。
第一种是过度设计。第二种是不设防。SharePad 走了第三条:所有权就是一个秘密。你知道这个 32 字节的数,你就是主人;不知道,你就只是读者。
这跟多数人的直觉相反——认证不是“你是谁”,是“你持有什么”。护照、密码、私钥,本质全是同一个东西。一个分享笔记本的“你是谁”没有任何意义,它要回答的唯一问题是“这个本子是不是你的”。32 字节随机数回答这个问题绰绰有余,还不用我存你的邮箱。
库里大概就这样:
slug -> 笔记内容、可见性、过期时间
token_hash -> SHA-256(编辑令牌)
没了。没有 users 表,没有 sessions 表,没有“忘记密码”。有 /recover 流程,但本质上,令牌丢了就是丢了——跟丢私钥一样。这是特性不是缺陷:系统里没有可以帮你找回的身份,就没有可以被社工掉的身份。
生产细节才是分水岭
这模型看着简单,做对很难。SharePad 有几个细节,每个想做“无账号所有权”的人都该抄。
令牌存哈希不存原文。库泄露,攻击者拿到的是 SHA-256,不是令牌本身。这跟存密码哈希是同一个道理。但很多做“分享链接”的工具根本没做到——它们的“魔法链接”令牌就明晃晃躺在表里。
Markdown 里的 HTML 要消毒。为什么?因为这是开放编辑的平台,别人能往你的笔记本里塞东西。不消毒,一段脚本就能在页面上跑。查看页拿不到编辑令牌,但编辑页里被注入脚本、窃取页面上下文里的凭证,这条路是通的。开放编辑模式下,任何能执行的东西都是攻击面。
过期和删除是分开的。默认 10 天过期,过期后查看链接立刻失效——但数据 3 天后才被定时任务真正删掉。这 3 天是恢复窗口:用户手滑设错了过期时间,还有得救。很多系统把“不可见”和“已删除”混成一件事,然后用户哭着来找你要数据。状态多一点,救命的余地就多一点。
第四个是我最喜欢的,因为它最不起眼:Node.js 的 fetch 上传大文件到 R2 时,请求里没有 Content-Length 头,R2 返回 411。作者修了,显式带上这个头。这种 bug 不会出现在任何架构图上,但它是真服务器和真服务之间真实发生的事。一个把 411 修掉的 side project,比一个画了十张架构图的 PPT 可信。
它自己承认的问题
编辑令牌在 URL 路径里。/e/{token}——这意味着它会进浏览器历史、进服务器访问日志、进任何中间代理的记录。作者在评论区自己承认了,说在考虑用 fragment(# 后面的部分不会发给服务器)或者首次访问时换成会话 cookie。
这是真问题,不是吹毛求疵。但注意顺序:他先把模型跑起来了,再承认模型里最弱的一环,再考虑补。不是先设计一套“完美的令牌传递协议”然后什么都没发布。这个顺序本身就是态度。
该砍的和没砍的
技术栈是 Next.js 16 + Supabase Postgres + Cloudflare R2 + PostHog。说实话,看到 Next.js 我皱了下眉头——一个 pastebin 要 App Router 和 Turbopack 干嘛。但转念一想,这是他的部署舒适区,self-host 的人 clone 下来就能跑,这个选择不构成批评。工具栈是口味,数据模型是判断。判断的部分他做对了。
图片处理挺克制:浏览器端压缩到最长边 1600px、WebP 82% 质量,每笔记本限 50 张。不上传原图再服务端转码——那才是小工具背不起的复杂度。
还有两个 GitHub Actions 定时任务:每三天 ping 一下 Supabase 防止免费项目被暂停,每周清理 R2 里的孤儿图片。这种活脏但必须有人干。不做第二个任务,存储账单会慢慢被没人引用的图片吃掉,而用户永远不会发现。
分析这块,PostHog 禁了自动捕获和会话录制,事件负载里明确不包含笔记内容、标题、slug、编辑令牌。一个匿名工具把遥测也做匿名,这是自洽。不自洽的版本我见过太多:口号是无注册无追踪,埋点里全是正文。
照妖镜
评论区有个人(Nitish Kumar)说这是“围绕实际威胁模型设计认证的范例”。我同意,还想把话说得更满:这不是范例,这是照妖镜。
照出来的妖,是那种“先上用户系统再说”的默认思维。好像任何带编辑功能的东西,第一步永远是 users 表。为什么?因为框架给了、教程教了、面试也问。没人停下来问一句:这个产品的威胁模型里,到底存不存在“身份”这个东西?
SharePad 的场景是“黑板式”临时协作——贴段笔记、发个链接、过十天自动消失。这种场景里的认证对象是“一次持有”,不是“一个账户”。作者自己也是这么定位的。场景想清楚了,砍掉用户表就不是偷懒,是设计。
反过来,硬上账户系统才是偷懒——工程师的懒惰:不去想这个产品到底需要什么,直接把最熟的那套模板拍上去。加一层是容易的,想清楚为什么不需要才是难的。
说句题外话——为什么我们这么怕让一个东西没有账号?好像没有 users 表的东西就不算产品。可想想你每天用的东西里,有多少的“账户”只是给你添了一次登录,别的什么都没换来。
扯回来。
一条规则
凡是加用户系统之前,先回答:丢一个“忘记密码”的功能,这个产品会死吗?不会的,你存的那个邮箱就是给人看的。
令牌即所有权,哈希即存储,过期即默认。这三句话撑起一个没有用户表的认证系统,还留了恢复窗口、防了注入、修了 411。
简单的东西能活得更久。这个连用户表都没有的东西,我赌它比很多“企业级”笔记平台活得久。