前端阅读 02026年5月31日 02:05
Tauri 常用系统 API 应该怎么选才安全?
Tauri 的系统 API 覆盖文件、窗口、对话框、通知、剪贴板、shell、快捷键和事件通信。它们看起来像前端函数,背后却是在调用系统能力,所以真正的问题不是“有哪些 API”,而是“哪些能力该开放给前端,开放到什么范围”。权限给大了,桌面应用会变成安全黑盒;权限给小了,功能又会在生产环境里突然不可用。文件和路径 API 怎么用?文件读写不要直接让前端传任意绝对路径,优先使用 app data、cache、document 等受控目录。用户主动选择的文件可以通过 dialog 获取路径,再交给后端命令处理。这样牺牲了一点自由度,但能避免前端 bug 误删用户文件。import { open } from '@tauri-apps/plugin-dialog';import { invoke } from '@tauri-apps/api/core';const path = await open({ multiple: false });if (typeof path === 'string') { await invoke('import_file', { path });}#[tauri::command]fn import_file(path: String) -> Result<String, String> { std::fs::read_to_string(path).map_err(|e| e.to_string())}Shell API 为什么要谨慎?打开链接和执行命令是两回事。open 外部 URL 通常风险较低,但执行系统命令必须限制参数、白名单程序和用户输入。不要把前端传来的字符串直接拼进 shell,这类问题在桌面应用里同样会变成命令注入。import { open } from '@tauri-apps/plugin-shell';await open('https://example.com/help');如果确实要执行命令,尽量在 Rust 侧封装固定动作,而不是暴露一个“runCommand”。边界是开发工具类应用可能需要更强 shell 能力,但也应该把工作区、命令集合和参数格式限制清楚。窗口、通知和剪贴板适合放前端吗?窗口最小化、聚焦、拖拽、主题切换这类 UI 能力放前端比较自然。通知和剪贴板要考虑用户预期:后台悄悄写剪贴板很冒犯,通知也要避免刷屏。更稳的做法是把这些能力集中封装成一层服务,统一处理权限、失败提示和平台差异。import { getCurrentWindow } from '@tauri-apps/api/window';const win = getCurrentWindow();await win.minimize();capability 配置应该怎么收敛?Tauri v2 推荐用 capability 声明窗口能访问哪些权限。开发期可以开得宽一些,但发布前要按功能逐项收敛。很多“本地正常、打包失败”的 API 问题,本质是 capability 没带进安装包,或者只给了主窗口权限,忘了给设置窗口、弹窗或托盘窗口。{ "identifier": "main-capability", "windows": ["main"], "permissions": [ "dialog:allow-open", "shell:allow-open", "notification:default" ]}多窗口应用要单独设计权限吗?需要。主窗口、设置窗口、登录窗口和托盘唤起的小窗口,能做的事情往往不一样。把所有窗口都塞进同一个 capability 最省事,但也会让低风险页面拿到高风险能力;按窗口拆权限更麻烦,却能减少误调用和安全暴露。实际项目里可以先按功能域拆,比如文件导入窗口只给 dialog 和受限文件权限,帮助页只允许打开外链。这样后续排查也更清楚。权限文件也应该进入代码评审范围。每新增一个系统能力,都要能说清楚由哪个窗口调用、为什么需要、失败时如何降级。追问文件 API 能不能直接开放全部权限?技术上可以,但不建议。全量文件权限会让任何前端漏洞都变得更危险,也会让安全审查很难解释。取舍是内部工具可以稍宽,面向普通用户的应用应尽量限定目录、扩展名和用户主动选择的路径。Dialog 选中文件后为什么还读不了?选择文件只是拿到路径,不代表你的读写权限、scope 或后端逻辑都正确。Tauri v2 下 capability、插件权限和命令实现都要匹配,否则开发时能跑,生产包可能失败。踩坑点是多窗口应用里权限只给了 main,设置页或二级窗口调用同一 API 就报错。Shell API 和 Rust Command 哪个更安全?固定业务动作优先写 Rust command,因为你可以在后端校验参数、限制路径和处理错误。Shell API 适合打开链接、启动外部应用这类明确行为,不适合承载复杂业务逻辑。边界是开发者工具需要调用 git、node、docker 时,可以做命令白名单,而不是开放任意命令。剪贴板和通知为什么要做用户提示?它们都属于用户能明显感知或事后追溯困难的能力。剪贴板被覆盖会影响用户正在做的事,通知过多会让应用显得像广告软件。更好的做法是在用户点击复制、导出完成、后台任务失败时触发,并提供明确反馈。API 迁移到 Tauri v2 最大的坑是什么?很多能力从内置 allowlist 迁到了独立插件和 capability 权限,导入路径也变了。只改 TypeScript import 不够,还要安装插件、在 Rust builder 注册,并写权限文件。迁移时建议一类 API 一类 API 地测,不要一次性替换全部,否则很难定位是权限、插件还是业务代码出了问题。