首页 / Tauri 2 入门教程 / 插件系统与权限模型

Tauri 2 入门教程

插件系统与权限模型

本教程共 48 篇 · 第 31 篇 · 更新于 2026-08-09 · 约 8 分钟阅读

TauriTauri 2 入门教程插件系统capabilitiespermissions权限模型

本节目标:读完你能说清一个官方插件在前后端分别叫什么名字、怎么接进项目,以及 2.x 的 capabilities / permissions 是怎么给前端「发许可证」的。

Tauri 把很多功能做成了插件(plugin):对话框、文件系统、系统托盘、HTTP 请求、通知……它们都是可插拔的模块,要用哪个装哪个,不用的就不进包里,应用体积小、攻击面也小。本章先讲插件怎么「接进来」,再重点讲 2.x 的权限模型(permission model)——这是 2.x 和 1.x 差别最大、也最容易让新手踩坑的地方。

前端包与 Rust 端的一一对应

每个官方插件都有「两面」:一面跑在 Rust 核心进程(真正干活),一面跑在前端(给你写 JS 时调用)。它们的名字是成对出现的,规律非常固定:

  • 前端 JS 包:@tauri-apps/plugin-<名字>
  • Rust 端 crate:tauri-plugin-<名字>

举几个你后面会遇到的例子:

功能前端包Rust 端 crate
对话框@tauri-apps/plugin-dialogtauri-plugin-dialog
文件系统@tauri-apps/plugin-fstauri-plugin-fs
系统通知@tauri-apps/plugin-notificationtauri-plugin-notification
HTTP 请求@tauri-apps/plugin-httptauri-plugin-http
全局快捷键@tauri-apps/plugin-global-shortcuttauri-plugin-global-shortcut

记住这个对应关系是关键:你在前端 import 的包名,永远对应 Rust 端那个同名 crate 的 .init()。两端缺一个,功能都跑不起来。

一个插件怎么接进项目

接一个插件要动三处:Rust 依赖、Rust 初始化、前端依赖。以对话框插件为例,完整流程是:

第一步,在 src-tauri 目录把 Rust 端加进 Cargo.toml

cd src-tauri
cargo add tauri-plugin-dialog

第二步,在 lib.rs 里用 .plugin(...) 把插件初始化挂到应用上:

// src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_dialog::init())   // Rust 端初始化
        .run(tauri::generate_context!())
        .expect("运行 Tauri 应用时出错");
}

第三步,前端装对应的 JS 包:

npm install @tauri-apps/plugin-dialog

三步走完,你就能在前端 import { open } from "@tauri-apps/plugin-dialog" 去调它了。文件系统和通知等其它插件,只是把名字换一下,流程一模一样。

Tip

官方脚手架提供了一条捷径:在 src-tauri 目录运行 cargo tauri add dialog(把 dialog 换成插件名),它会一次性帮你加 Rust 依赖、初始化插件、装好前端包,还能顺手把默认权限写进 capability。新手用它最省心。

2.x 的权限模型:capabilities + permissions

2.x 有个核心规矩:前端默认什么系统能力都调不了,必须显式授权。你装了插件、调了 .init(),前端也 import 成功了,但如果没在 capability 里给这个插件「发许可证」,运行时一调用就会被安全层拦下,报类似 dialog.open not allowed 的错误。

这套机制由两层组成:

  • permission(权限):描述「某个命令能不能被调」。每个插件自带一组 permission,比如 dialog:allow-open 表示「允许调打开对话框这个命令」。标识符格式是 <插件名>:<命令>,例如 fs:allow-read-file
  • capability(能力):把若干 permission 打包,并指定「授予哪些窗口 / WebView」。它是一份 JSON 文件,放在 src-tauri/capabilities/ 目录里。

换句话说,permission 是「单张许可证」,capability 是「把许可证发给谁的一张派单」。前端调用是否被放行,由它所在的窗口在不在某个 capability 的 windows 列表里、且那个 capability 含不含对应 permission 来决定。

兼容说明:1.x 默认放开 vs 2.x 最小权限

Note

1.x 与 2.x 权限模型的区别(仅本节说明,正文仍以 2.x 为准)

  • Tauri 1.x:在 tauri.conf.json 里用 allowlist 配置。默认情况下,只要你装了插件,开发环境里前端基本就能直接调,没有细到「哪个窗口、哪个命令」的显式授权概念,权限相对宽松。
  • Tauri 2.x:彻底改为 capabilities + permissions 模型。所有插件命令默认全部拒绝,必须由你在 capabilities/*.json 里显式列出要授权的 permissions,并指定作用到哪些 windows。即便在开发模式,没授权也会被拦。每个窗口拿到的权限是「刚好够用」的最小集合。

一句话:1.x 是「默认放开、按需收紧」;2.x 是「默认全关、按需显式授权」。这也是 2.x 从 1.x 升级后,原本能跑的 invoke 突然报 not allowed 的最常见原因——不是代码错了,是没补 capability。

capabilities 文件怎么写

一个典型的 capability 文件长这样,放在 src-tauri/capabilities/default.json

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "main-capability",
  "description": "主窗口的能力与权限",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "dialog:default",
    "fs:default"
  ]
}

逐字段说明:

  • $schema:让编辑器能对权限名做自动补全,照抄即可。
  • identifier:这份 capability 的名字,全局唯一。
  • windows:这份权限授予哪些窗口,写窗口的 label(注意是 label,不是标题)。["main"] 表示只给主窗口;写 ["*"] 则给所有窗口。
  • permissions:真正授权的权限列表。core:default 是核心能力的基础包;dialog:defaultfs:default 是各插件的「默认权限全家桶」,一次性开放该插件常用命令。

多数插件都提供一个 :default 集合,开它就够用;想要更克制,就把 :default 换成具体的 :allow-xxx(见第 32 章 fs 示例)。

Warning

capability 是按窗口 label 生效的,不是按窗口标题。很多新手把窗口标题写进 windows 却怎么都不生效,问题就出在这里。窗口的 label 是在 tauri.conf.json 或创建窗口时定的那个字符串。

permissions 还能带 scope

有些权限不只是「能不能调」,还管「能访问哪」。文件系统就是典型:你允许读文件,但不能让前端读你整个硬盘。于是 permission 之外还有一层 scope(作用域),用来圈定允许访问的具体路径。

scope 写在 permission 的对象形式里,例如(细节第 32 章展开):

{
  "identifier": "fs:allow-read-file",
  "allow": [{ "path": "$APPDATA/**" }]
}

这表示「允许调读文件命令,但只允许读 $APPDATA 及其子目录下的内容」。这种「命令权限 + 路径作用域」的组合,才是 2.x 安全模型的精细之处。deny 优先级高于 allow,圈进 deny 的路径即使 allow 了也会被挡。

小结

Tauri 插件分两面:前端 @tauri-apps/plugin-<名> 对应 Rust 端 tauri-plugin-<名>,接项目要在 Rust 加依赖、.plugin(...init())、前端装 JS 包三处动手。2.x 的安全核心是 capabilities + permissions:默认全拒绝,必须显式授权——permissions 是单张许可证(如 dialog:allow-open),capabilities 是把许可证按窗口派发的清单。和 1.x 的 allowlist 默认宽松不同,2.x 改成最小权限、按需显式开放,这也是升级后命令突然 not allowed 的根源。部分权限(如 fs)还能叠加 scope 进一步限制可访问的路径。