好的,我们分别来写这两部分。
Windows:exe、msi、nsis 安装包配置
Tauri 对 Windows 安装包的支持非常灵活,一次构建就能生成多种格式,无需复杂的第三方打包脚本。在项目根目录的 tauri.conf.json 中,通过 bundle 配置块下的 windows 字段,可以分别控制 .exe 安装程序、.msi 安装包以及 .nsis 自解压安装包的行为。
1. 基础 exe 安装程序
默认情况下,Tauri 会生成一个基于 WiX 的 .msi 安装包和一个 .exe 安装程序。.exe 安装程序就是最常见的双击安装向导,支持自定义安装路径、桌面快捷方式等基础功能。你可以在 tauri.conf.json 中这样配置:
{
"bundle": {
"active": true,
"windows": {
"wix": {
"language": "zh-CN",
"template": null
},
"nsis": null
}
}
}
wix.language 用于指定安装界面的语言(如中文简体 zh-CN),其他参数保持默认即可生成适合分发的 .exe。
2. MSI 安装包
如果需要批量部署或通过组策略分发,.msi 是更好的选择。它由 WiX 工具集自动生成,可以与企业内部的软件管理工具(如 SCCM)集成。想单独控制 MSI 包的属性(如升级机制、安装条件),可以自定义 WiX 模板文件(template 字段指向自定义 .wxs 文件),但大多数场景下 Tauri 提供的默认 MSI 模板已足够使用。
3. NSIS 安装包
NSIS(Nullsoft Scriptable Install System)生成的安装包体积更小、定制性更强,很多经典 Windows 软件(如 7-Zip)都在使用。如果你的用户群体偏爱“一选到底”的轻量安装体验,或者你需要在安装过程中加入勾选许可协议、检测环境组件等高级逻辑,可以启用 NSIS:
{
"bundle": {
"active": true,
"windows": {
"nsis": {
"installMode": "currentUser",
"languages": ["English", "SimpChinese"],
"displayLanguageSelector": true
}
}
}
}
installMode 可设为 currentUser 或 perMachine,前者仅对当前用户安装(无需管理员权限),后者需要提升权限安装到所有用户。通过自定义 .nsi 模板,还可以嵌入复杂的安装逻辑,例如注册组件、写入注册表键值、执行静默卸载等。
实际推荐
- 面向普通消费者的工具类应用,用默认的
.exe(WiX)即可; - 企业分发或需要静默部署时,优先选择
.msi; - 如果追求极致压缩率和高定制性,或者你需要一个可以“刻录到光盘”的安装界面,用 NSIS 最合适。
Tauri 构建命令(taro build)会根据你的配置自动生成对应的格式,无需额外安装打包工具。
禁用危险 API、限制远程域名
安全是 Tauri 架构的核心,而“最小权限原则”的实现主要依靠两个机制:命令白名单 和 安全配置(capability / allowlist)。你可以在 tauri.conf.json 或 Tauri v2 的 capabilities 文件中,精确控制前端可以调用哪些 Rust 命令,以及可以从哪些远程域名加载内容,从而彻底堵住危险通道。
1. 禁用危险 API(命令白名单)
在 Tauri 中,前端 JavaScript 不能随意调用任何 Rust 函数,必须通过 invoke 调用已注册的命令。为了防止恶意页面(或被注入的脚本)利用系统 API,你需要显式声明允许的前端命令列表。
Tauri v1 中,这主要通过 allowlist 完成:
{
"tauri": {
"allowlist": {
"fs": {
"scope": ["$APPDATA/*"]
},
"shell": {
"open": "com.nonexistent.scheme" // 禁止打开任意 HTTP/HTTPS 链接
},
"protocol": { "asset": true, "assetScope": ["$RESOURCE/*"] }
}
}
}
在 Tauri v2 中,安全模型更精细,改用 capabilities 文件。例如,创建一个 capabilities/default.json:
{
"identifier": "default",
"description": "默认权限",
"windows": ["main"],
"permissions": [
"core:default",
"fs:allow-read-text-file",
{
"identifier": "fs:deny-write-text-file",
"allow": false
}
]
}
这里明确拒绝了对 fs:write-text-file 的调用,即使前端代码尝试 invoke 该命令,也会被 Rust 运行时拦截,返回错误。你甚至可以基于命令参数进行更细粒度的过滤(如只允许读取某个目录下的文件),从而彻底杜绝路径遍历攻击。
2. 限制远程域名
同样的,你可以限制 WebView 能访问哪些外部资源,防止前端页面被重定向到恶意站点,或加载未授权的第三方脚本。
在 Tauri 的 CSP(内容安全策略)中配置:
{
"tauri": {
"security": {
"csp": "default-src 'self'; script-src 'self'; connect-src 'self' https://api.your-app.com;"
}
}
}
connect-src 'self' https://api.your-app.com 表示只有当前源和指定的 API 域名才能被 fetch 或 XHR 调用,其余一概拒绝。如果想彻底禁止所有远程内容,可以将 default-src 设为 'self'。
防盗链与URL白名单
如果你的应用需要打开系统浏览器访问外部链接,也应该在 Rust 命令中校验 URL 是否属于白名单域名,而不是直接传给系统 shell:
#[tauri::command]
fn open_url(url: String) {
let allowed_domains = ["your-app.com", "docs.your-app.com"];
if let Ok(parsed) = url::Url::parse(&url) {
if let Some(domain) = parsed.host_str() {
if allowed_domains.contains(&domain) {
open::that(url).unwrap();
}
}
}
}
这样即便前端代码被人为篡改,也无法通过你的应用打开钓鱼网站。
实际效果
做了这些配置后,即使你的前端页面被植入恶意代码(比如通过 npm 依赖投毒),攻击者也无法调用未授权的系统 API,也无法向不受信任的服务器发送数据。这种防御不是“依赖开发者每次检查”,而是由框架架构保证的,从根本上降低了安全风险。