Insomnia 模板标签沙箱插件如何在 package.json 声明 insomnia.permissions 模块与能力授权
【免费下载链接】insomniaThe open-source, cross-platform API client for GraphQL, REST, WebSockets, SSE and gRPC. With Cloud, Local and Git storage.项目地址: https://gitcode.com/GitHub_Trending/in/insomnia
当 Preferences → Scripting 中的Run template tags in sandbox设置开启后,插件的模板标签run()会在一个隔离的 QuickJS 沙箱里执行。沙箱采用**默认拒绝(default-deny)**模型:插件只能访问package.json中显式声明的模块和能力。如果你的模板标签插件要require非基线模块,或要调用context.network、context.store等主机桥接功能,就必须先在插件的package.json里声明insomnia.permissions,否则会直接报错。
本文以仓库内的 权限说明文档 和 演示插件 为依据,给出声明格式、两个授权轴的可选值、加载步骤和验证方法。
声明格式:insomnia.permissions 的两个轴
在插件的package.json中,insomnia字段下添加permissions对象,它包含两个相互独立的数组:
{ "insomnia": { "permissions": { "modules": ["events"], "capabilities": ["network"] } } }modules:决定沙箱内require(x)允许返回什么;capabilities:决定标签可以调用哪些context.*主机桥接分组。
仓库自带的演示插件 package.json 是一份真实声明:
{ "name": "insomnia-plugin-sandbox-demo", "version": "1.0.0", "description": "Demo plugin to manually verify the QuickJS template-tag sandbox path", "main": "index.js", "insomnia": { "name": "sandbox-demo", "description": "Demo plugin to manually verify the QuickJS template-tag sandbox path", "permissions": { "modules": ["events", "uuid"], "capabilities": ["storage"] } } }modules 轴:基线与可授予模块
- 基线模块(无需声明):
path、crypto; - 可授予模块:沙箱注册表中的其他模块,声明后才会加入你的授权范围。文档中列出的有:
- 纯 JS 重实现:
events(以及 M2 里程碑后继续增加的模块); - 经过审核的 npm 库(由 Insomnia 固定版本并预先打包):
uuid、ajv。这些库只在插件声明它们时才加载,来源是沙箱独立的固定版本安装(src/templating/sandbox/vendored/pkg/),与 App 自身依赖的ajv/uuid相互独立,避免随应用依赖升级而漂移。
- 纯 JS 重实现:
注意一条容易踩中的规则:对经过审核的库要在run()内部require,而不是顶层。Insomnia 发现插件标签时是在宿主进程中加载入口文件,而uuid/ajv只存在于沙箱注册表中,顶层require('uuid')/require('ajv')会解析失败;从标签的run()里 require 即可。相对路径的require('./util')在顶层没有问题。
capabilities 轴:基线与需声明的能力
没有某个 capability,对应的context分支会直接不存在(例如context.network === undefined),因此可以在代码里做特性检测并优雅降级。
| Capability | 授予的内容 | 是否基线 |
|---|---|---|
render | context.util.render | 是(基线) |
models.read | 只读的context.util.models.*查找 | 是(基线) |
util | context.util.nodeOS/decode/encode | 是(基线) |
crypto | require('crypto')主机函数 | 是(基线) |
network | context.network.* | 需声明 |
storage | context.store.* | 需声明 |
fs-read | context.util.readFile | 需声明 |
app | context.app.*、context.util.openInBrowser | 需声明 |
credentials(云厂商凭据读写)保留给第一方 bundle 插件,社区模板标签插件即使声明也无法获得——它高于模板标签表面的能力上限。
加载插件并声明权限的操作路径
以下流程来自演示插件的 README,适用于开发环境下手动验证:
- 在仓库根目录运行应用:
npm run dev; - Preferences → Plugins →Reveal Plugins Folder,把插件目录(如
insomnia-plugin-sandbox-demo)复制进该目录; - 点击Reload Plugins;
- Preferences → Scripting → 切换Run template tags in sandbox (experimental);
- 在请求的 URL 或 header 里插入模板标签(或手动输入标签语法),观察预览随开关切换而变化。
存量插件的迁移路径:没有声明permissions块的插件按基线授权运行。当它尝试使用非基线模块时,会看到一条一次性通知,指明需要添加的具体授权项;按提示加上insomnia.permissions块后重新加载插件即可。
结果验证:如何用探针标签确认授权生效
演示插件 index.js 提供了一组探针标签,每个标签对应一种授权验证场景,都来自文档明确的预期行为:
{% requireprobe 'path' %}:渲染a/b,说明基线授权、注册表实现生效;{% requireprobe 'fs' %}(或未声明的 npm 包):失败,报错Module 'X' not permitted by manifest;{% eventsprobe %}:因为该插件声明了modules: ["events"],渲染events-ok。未声明events的插件会得到Module 'events' not permitted by manifest;{% capabilityprobe %}:因为声明了capabilities: ["storage"],完成一次context.store的 set/get 往返并渲染storage-ok。未声明storage会得到Capability 'storage' not granted — add it to insomnia.permissions.capabilities;{% vendoredprobe %}:因为声明了modules中的uuid,渲染uuid=ok(文档示例输出);{% sandboxprobe 'hi' %}:沙箱开关关闭时渲染hello | ran in: main-process | arch via bridge: <arch>,开启时渲染hello | ran in: sandbox | arch via bridge: <arch>,其中ran in的切换证明标签确实在沙箱内执行。
此外,Preferences → Plugins 界面会展示每个插件声明的权限(演示插件会列出modules: events),这是不写请求也能快速核对声明是否被解析的入口。
常见报错与限制
| 现象 | 含义与处理 |
|---|---|
Module 'X' not permitted by manifest | require('X')的模块未声明,把X加入insomnia.permissions.modules后重新加载插件 |
Module 'X' not available in sandbox | 模块已声明但 Insomnia 的沙箱注册表尚未收录,需等待其加入注册表 |
Capability 'X' not granted — add it to insomnia.permissions.capabilities | 对应的context.*分支缺失,把X加入capabilities数组 |
| 插件卡片上的 manifest 警告 | 声明格式错误(如modules不是数组、条目不是非空字符串)不会抛异常,而是降级为基线访问并附带可读警告,插件本身仍会加载 |
解析逻辑可以在 permissions.ts 中核对:非数组轴产生警告并忽略(回到基线);数组内只保留非空字符串并去重;permissions字段缺失时视为"未声明",与"声明了但为空"是两种不同状态。
其他边界:
- 插件自己的
node_modules永远不会被引用——裸require('uuid')总是解析到注册表的审核版本,插件无法自带一个替代实现;只有插件目录内的.js/.json文件会被加载(node_modules和点目录被跳过); - 多文件插件支持
require('./util')、require('../shared')、require('./lib')(解析到./lib/index.js),均从插件自身源码目录解析; - 第一方 bundle 插件是受信任的,直接获得全部模块与能力,无需声明。
小结
声明insomnia.permissions的完整闭环是:在package.json的insomnia字段下按两个轴写modules和capabilities数组 → 复制插件到 Plugins Folder 并 Reload → 开启Run template tags in sandbox→ 用探针标签(或直接跑你的标签)确认渲染结果,或查看 Preferences → Plugins 卡片上列出的声明。遇到not permitted/not granted报错时,按报错中点名的模块名或能力名补齐对应数组即可。
【免费下载链接】insomniaThe open-source, cross-platform API client for GraphQL, REST, WebSockets, SSE and gRPC. With Cloud, Local and Git storage.项目地址: https://gitcode.com/GitHub_Trending/in/insomnia
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考