Puter 文件系统 API 实战:使用 puter.fs.getReadURL() 生成免鉴权临时只读链接 📅 发布时间:2026/9/9 15:28:06 👁 浏览次数: Puter 文件系统 API 实战使用 puter.fs.getReadURL() 生成免鉴权临时只读链接【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puterputer.fs.getReadURL()是 Puter 云端文件系统Puter.js FS 模块中用于为单个文件生成临时可读 URL的方法。它返回的链接携带一把一次性授权的访问令牌任何拿到链接的人都可以在有效期内直接读取该文件而无需登录或携带用户凭据。本文基于仓库文档与源码完整讲解该 API 的语法、参数、有效期规则、底层鉴权原理、撤销机制以及测试验证帮助你在网站、App、Node.js 与 Workers 场景下安全地把指定文件公开一段时间落地为可复用的方案。核心功能把鉴权读取变成链接读取在 Puter 的文件体系中一切读写操作默认都要经过用户身份校验SDK 在每次请求前会执行ensureAuthenticated见 scaffold.js。当你需要把某个文件临时交给他人例如分享给未登录用户、在第三方应用中加载资源时不希望对方拥有你的账号权限只希望他能在限期内读到这一个文件。puter.fs.getReadURL()解决的正是这个诉求服务端为指定文件签发一个窄权限访问令牌仅含fs:uid:read读权限SDK 把令牌拼进一个指向/token-read的 URL 并返回给你拿到 URL 的任何人都能在有效期内免登录下载/查看该文件内容无法越权访问文件系统中其他任何资源。官方文档将其定位为 Generate a URL that can be used to read a file即 getReadURL.md 所述为用户的 Puter 文件系统中某一份文件生成一个任何人都可读取的临时 URL。方法语法该方法支持两种等价的调用形式可选参数与回调均可不传puter.fs.getReadURL(path); puter.fs.getReadURL(path, expiresIn);根据 SDK 中操作的定义getReadUrl.jspath与expiresIn属于位置参数positional argumentsconst getReadURL defineOperation({ positional: [path, expiresIn], // ... });defineOperation脚手架见 scaffold.js同时还兼容以下调用惯例puter.fs.getReadURL(options)直接传入一个对象如{ path, expiresIn }puter.fs.getReadURL(path, expiresIn, successCallback, errorCallback)沿用旧的基于回调的写法位置参数也兼容历史的下划线命名firstDefined会对 snake_case 与 camelCase 一并解析。这意味着你既可以用现代async/await风格也可以沿用老代码的回调风格。参数说明pathString必填要读取的文件的路径。可以是用户的绝对路径也可以是~开头的家目录路径如~/myfile.txt。SDK 内部会先对该路径执行一次stat以获取文件元数据再据此构建授权信息。注意该方法只对文件有效。若传入的是目录路径SDK 会直接抛出错误Cannot create readUrl for directory对应测试用例 getReadURL of a directory rejects见 fs.suite.ts。这与read/write的语义一致——URL 直读模型不支持目录公开需要目录级共享请改用share系列 API。expiresInString | Number可选URL 的有效时长采用jsonwebtoken库的时长语义字符串形式24h、30d、1h等允许的单位后缀如下表数字形式以秒为单位的数字如3600表示 1 小时不传时默认值为24hSDK 中写死为options.expiresIn ?? 24h。单位后缀含义示例s秒900s即 15 分钟m分钟5mh小时1h、24h默认d天30dw周1wy年1y服务端对时长的解析与 jsonwebtoken 保持一致。在 AuthService.ts 的#hardExpiryFromExpiresIn私有方法中可以看到实现细节字符串会按正则^(\d)\s*([smhdwy])?$解析因此数字与单位之间允许存在空格如24 h未写单位时按秒处理各单位的换算倍率s:1、m:60、h:3600、d:86400、w、y在该方法内逐一声明。需要留意的是访问令牌携带的是行级row-level硬过期时间不存在滑动续期机制——URL 一旦签发其生命周期在签发时刻即已固定。返回值该方法返回一个Promiseresolve 后得到一个URL 字符串。该 URL 可直接用于读取对应文件。const url await puter.fs.getReadURL(~/myfile.txt);从 SDK 的transform逻辑getReadUrl.js可以看到 URL 的真实形态transform: ({ token }) ${this.APIOrigin}/token-read?uid${encodeURIComponent(uid)}token${encodeURIComponent(token)},即{API 源地址}/token-read?uid文件uidtokenJWT访问令牌。其中uid目标文件的唯一标识由先前的stat结果提供token服务端签发的访问令牌JWTAPIOrigin当前 Puter 实例的 API 地址自托管环境会指向你自己的服务器。完整示例基础用法默认 24 小时// 在已通过 puter.js 完成登录/授权的环境网页、App、Node.js、Workers中 const url await puter.fs.getReadURL(~/myfile.txt); console.log(url); // https://api.puter.local/token-read?uid...token...自定义有效期// 30 天后过期 const urlA await puter.fs.getReadURL(~/report.pdf, 30d); // 15 分钟后过期字符串 const urlB await puter.fs.getReadURL(~/preview.png, 15m); // 用秒数指定3600 秒 1 小时 const urlC await puter.fs.getReadURL(~/data.json, 3600);消费者侧无需任何请求头即可读取测试用例 getReadURL grants unauthenticated read access见 fs.suite.ts验证了这样一个关键行为对返回 URL 发起fetch时不携带任何 Authorization 请求头也能成功读取文件内容因为令牌就在 URL 上const url await t.puter.fs.getReadURL(path); const resp await fetch(url); // 无 Authorization 头 resp.status; // 200 await resp.text(); // 文件原文这也直接佐证了该链接的可外传属性可以把它贴给任何人、放在 HTMLimg src/a href中由浏览器无脚本地完成下载或预览。目录会报错const url await puter.fs.getReadURL(~/my-directory); // 抛出Cannot create readUrl for directory底层工作原理一次调用背后的完整链路getReadURL并不是把文件上传成一个静态公网地址而是签发一张范围极窄的临时通行证。结合 SDK 与后端代码一次调用的完整链路如下定位文件SDK 侧 statgetReadUrl.js 先调用stat.call(this, options.path)拿到目标文件的uid与is_dir。若is_dir为真则直接拒绝避免目录被 URL 化。签发访问令牌SDK 请求 → 后端SDK 向POST /auth/create-access-token发起请求请求体为{ expiresIn: 24h, permissions: [fs:文件uid:read] }该权限字符串fs:${uid}:read的含义是仅对 uid 对应的这一个文件条目授予read动作除此之外一无所能。后端铸造令牌服务端核心路由定义于 AuthController.tsPost(/auth/create-access-token, { subdomain: api, requireAuth: true, rateLimit: CREDENTIAL_MINT_LIMIT, }) async handleCreateAccessToken(req: Request, res: Response): Promisevoid { const { permissions, expiresIn, label } req.body ?? {}; // ...校验 permissions 数组非空... }签发方actor必须是一个已登录用户requireAuth: true且在AuthService.createAccessToken中对无用户身份的 actor 抛出 403这保证了只有文件所有者本人能替自己的文件铸造公开链接。令牌签发遵循#hardExpiryFromExpiresIn计算出的硬过期时间权限明细落库到access_token_permissions最终向调用方返回 JWT。拼装 URLSDK 侧 transform拿到{ token }后SDK 拼出${APIOrigin}/token-read?uid...token...作为最终返回值。消费读取后端 token-read 路由/token-read是 GET 路由注册于 LegacyFSController.ts其配置刻意强调了免验证、免登录读的定位router.get( /token-read, { subdomain: api, requireVerified: false, // 不要求邮箱验证 allowAccessToken: true, // 允许 URL 内访问令牌 rateLimit: FS_SIGNED_READ_LIMIT, // 使用网络维度key 不依赖用户的限流 }, this.tokenRead, );处理器从 query 中取出token交给鉴权链路校验验证通过即按 uid 把文件内容流式返回给请求方。由于访问令牌不一定携带用户身份该路由的限流预算与其它签名路由一致地按网络维度计算源码注释原文An access token may or may not carry a user, so this shares the network-keyed budget the other signed routes use。安全边界与撤销机制理解该 API 的安全模型有助于正确地使用它链接即凭据URL 自带令牌、无额外鉴权任何获得链接的人都等于获得了这张限时单文件读票。因此应把返回值当作敏感凭据对待只在确有需要时传播。权限被压缩到单个文件令牌仅包含fs:uid:read一个作用域无法枚举目录、无法写文件、无法访问文件系统中的其它条目。有效期就是硬边界默认24h过期后令牌校验失败访问令牌带行级硬过期。后端在过期校验上同样严谨——例如签名式 URL 的verifySignature会拒绝一切已过期的签名并抛出 403参见 fileSigning.ts。可主动吊销与getReadURL配套Puter.js 提供了puter.fs.revokeReadURL(urlOrTokenOrUuid)实现见 revokeReadUrl.js。它接受完整的/token-readURL、裸令牌或令牌 UUID并调用POST /auth/revoke-access-token完成吊销。后端会先从 URL 中提取 JWT对/token-read片段做正则解析见 AuthController.ts再执行撤销。源码注释提醒撤销接口强制要求 Cookie 会话身份一个被泄露的访问令牌不能静默吊销它自己的兄弟姐妹——防止攻击者用偷来的令牌反制授权者。一个实用的安全习惯是文件只在需要公开的窗口期内有效默认时长尽量短如1h窗口结束后即使 URL 泄露也无法再读取如果提前不再需要应显式调用revokeReadURL。与相关 API 的边界划分在 Puter.js 文件模块中index.js围绕文件对外可见性存在多个易混淆的 API选用时应区分它们API定位区别要点getReadURL生成免鉴权的临时只读 URL本文主题URL 内含访问令牌可设置有效期、可吊销仅限单文件读取revokeReadURL吊销已生成的临时 URL输入urlOrTokenOrUuid撤销后链接失效share/unshare建立持久的共享关系面向需要长期、可管理如可枚举、可取消的共享场景语义更接近共享权限管理sign返回带签名的文件条目对象后端签名式文件 URL 另有一套基于signature/expires参数的机制参见 fileSigning.ts其中read_url/write_url/metadata_url字段分别对应读、写、元数据签名地址在实际业务中getReadURL适合一次性外发、短生命周期的文件交付需要长期、结构化、可审计的共享例如多用户协作文档则应优先考虑share。支持平台与验证依据文档 frontmatter 声明该方法可用于websites、apps、nodejs、workers四种运行环境即无论代码运行在浏览器站点、App 内嵌环境、Node.js 服务端还是 Puter Workers 中均可调用。仓库内的端到端测试为上述行为提供了可复现证据见 src/puter-js/tests/api/suites/fs.suite.tsgetReadURL grants unauthenticated read access写文件 → 生成 URL → 断言 URL 包含/token-read→ 无鉴权fetch得到200与文件原文getReadURL of a directory rejects对目录调用getReadURL会按预期 reject。小结puter.fs.getReadURL(path, expiresIn)用一次调用把服务端签发单文件窄权限令牌 客户端拼装可外传 URL的复杂流程封装干净输入一个文件路径与可选有效期默认24h支持s/m/h/d/w/y单位或秒数返回一个任何人免登录即可读取该文件的临时 URL令牌权限被严格限制在fs:uid:read目录不可 URL 化可随时通过revokeReadURL吊销。配合 read.md、share.md 等相邻 API 文档阅读可以进一步构建一套完整的文件安全暴露方案短生命周期用getReadURL 显式吊销长周期共享交给share体系。【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考