权限:最小够用原则
本教程共 45 篇 · 第 21 篇 · 更新于 2026-08-13 · 约 3 分钟阅读
本节目标:分清三类权限声明,学会在 wxt.config.ts 里声明权限,并掌握「最小够用」的设计步骤。
权限是什么
权限(permissions)是扩展向浏览器申请的「能力清单」。用户安装扩展时,浏览器会展示这些声明。权限越多,警告越吓人,上架审核的风险也越高。所以原则只有一个:够用就好,越少越好。
WXT 项目里没有 manifest.json,权限统一写在 wxt.config.ts 的 manifest 字段中(manifest 生成机制见 §25):
export default defineConfig({
manifest: {
permissions: ['storage', 'tabs'],
},
});
三类声明别搞混
新手最容易混的是这三个概念。它们相关,但不是一回事:
permissions:允许调用某类扩展 API,比如storage、tabs、scripting。host_permissions:允许对某些站点做受限操作或跨源请求,比如https://www.google.com/*。- 内容脚本的
matches:决定脚本自动注入到哪些页面,如 §11 所述。
export default defineConfig({
manifest: {
permissions: ['scripting'],
host_permissions: ['https://api.example.com/*'],
},
});
一个功能常常要同时声明好几类。比如用 scripting.executeScript 往网页注入代码,既要 scripting API 权限,也要对应页面的授权。反过来,声明了 host permission 不代表自动有内容脚本,matches 是另一份独立声明。
NoteMV3 里
host_permissions是独立字段;MV2 没有这个字段,主机权限直接以 URL 形式混在permissions数组里写。WXT 构建时会按目标清单版本自动转换,但写配置时心里要有数。
WXT 会自动加哪些权限
大部分权限要手动声明,只有两种例外:
- 开发模式(dev)下自动加
tabs和scripting,用来支持热重载。 - 项目里有 sidepanel 入口时,自动加
sidepanel权限。
所以「开发时没写也有」的权限,打包后可能就没有了。一切以产物里的 manifest 为准。
不同浏览器,不同权限
各家浏览器支持的权限不一样。同一个字段,Chrome 和 Firefox 往往要给出不同列表。用 manifest 函数按浏览器分支:
export default defineConfig({
manifest: ({ browser }) => ({
permissions:
browser === 'chrome'
? ['storage', 'favicon', 'declarativeNetRequest']
: ['storage', 'webRequest'],
}),
});
同理,MV2 和 MV3 需要的 host_permissions 也可能不同,可以用 manifestVersion 分支。
最小权限设计六步
mkext 项目教程总结了一份开发新功能前的自问清单,按顺序回答:
- 功能必须在哪个运行环境执行?(后台、内容脚本、弹窗……)
- 需要哪个浏览器 API?
- 只操作用户当前主动选择的标签页,还是长期匹配固定站点?
- 能否把范围缩小到指定域名和路径?
- 权限是安装时必需,还是可以做成 optional permission,需要时再请求?
- UI 有没有向用户解释读取和使用了哪些数据?
不要先加一堆宽泛权限,再逐个试哪个能消掉报错。权限收敛是设计出来的,不是试出来的。
host_permissions 从环境变量动态取
站点列表写死很难维护。mkext 的做法是从环境变量取 origin,再拼成权限:
// wxt.config.ts
const getAuthHostPermission = () => {
const authUrl = new URL(
import.meta.env.VITE_AUTH_URL ?? 'http://localhost:3000',
);
return `${authUrl.origin}/*`;
};
export default defineConfig({
manifest: {
host_permissions: [
getAuthHostPermission(),
'https://api.example.com/*',
],
},
});
环境变量是 https://app.example.com/path 时,权限会收敛成 https://app.example.com/*。换环境只改配置,不动代码。
验证最终权限
WXT 会按入口自动生成一部分 manifest 字段,你手写的只是其中一部分。跑一次构建,打开产物确认最终结果:
wxt build
# 检查 .output/chrome-mv3/manifest.json
Tip内容脚本的
matches与权限声明相互独立,但用户感知相同:都是「扩展能碰到哪些网站」。设计时把它们放在一起考虑,站点范围保持最小,如 §11 所述。
小结
permissions/host_permissions/ content script 的matches作用域不同,别混为一谈。- 最小权限是原则:先不加权限开发,最后按需补,optional permissions 给运行时兜底。
- 权限收敛是设计出来的,不是试出来的——开发新功能前先过一遍自问清单。