本文将详细介绍 Deno 2.0 的权限系统,重点对比主包和第三方包的权限控制机制,分析不同的权限授予方式,并通过代码和配置文件演示如何有效管理这些权限。
前文提要:Deno2.0与Bun对比,谁更胜一筹?,介绍参考 带你掌握Deno2.0的安装到项目构建全流程
本文主要介绍其权限系统、也是与其它js运行时不一样的部分
一、Deno 权限系统概述
Deno 的权限系统旨在通过限制代码对系统资源的访问,确保开发者能够清楚地控制应用的行为并减少安全风险。Deno 使用了“显式权限”模型,默认情况下,所有对文件系统、网络和环境变量等关键资源的访问都被禁止,开发者需要通过命令行参数或特定 API 明确授予这些权限。
Deno 的主要权限包括:
- 文件系统访问 (
--allow-read
,--allow-write
) - 网络访问 (
--allow-net
) - 环境变量访问 (
--allow-env
) - 运行子进程 (
--allow-run
) - 高精度时间访问 (
--allow-hrtime
)
二、主包和第三方包权限控制对比
Deno 在权限管理上对主包(开发者编写的代码)和第三方包采用了相同的安全模型。无论是主包还是第三方包,Deno 都要求开发者通过显式授权来启用权限。这和其他运行时(比如 Node.js)不一样,在 Deno 中每个模块和依赖包默认都没有权限。
资源类型 | 主包权限控制方式 | 第三方包权限控制方式 | 说明 |
---|---|---|---|
文件系统访问 | 显式通过命令行参数 | 显式通过命令行参数 | 开发者需授予同样的文件系统访问权限 |
网络访问 | 显式通过命令行参数 | 显式通过命令行参数 | 无区别对待,需要显式授权 |
环境变量访问 | 显式通过命令行参数 | 显式通过命令行参数 | 权限统一,需授权 |
子进程访问 | 显式通过命令行参数 | 显式通过命令行参数 | 主包和第三方包无差别 |
示例代码:
// 读取文件,需授予 --allow-read 权限
const fileContent = await Deno.readTextFile("./example.txt");
console.log(fileContent);
// 发起网络请求,需授予 --allow-net 权限
const response = await fetch("https://example.com");
const data = await response.text();
console.log(data);
运行命令:
deno run --allow-read --allow-net app.ts
在上述示例中,如果没有正确授予文件读取和网络访问权限,Deno 会报错提示权限不足。
三、多种权限授予方式对比
Deno 允许通过多种方式授予权限,这为开发者提供了灵活性,尤其是在不同场景下可以使用合适的权限管理策略。
1. 命令行参数方式
这是最常见的方式,开发者在运行 Deno 程序时通过命令行参数显式授予权限,例如 --allow-read
、--allow-net
等。
优点:
- 简单直观
- 适合开发阶段快速调试
缺点:
- 需要开发者记住并维护命令行权限
- 对复杂应用来说管理不便
2. 权限 API
Deno 提供了权限管理的 API,允许开发者在代码中动态检查和请求权限。API 的主要方法包括:
Deno.permissions.query()
Deno.permissions.request()
Deno.permissions.revoke()
示例代码:
const status = await Deno.permissions.query({
name: "read" });
if (status.state !== "granted") {
console.log("请求文件读取权限");
const requestStatus = await Deno.permissions.request({
name: "read" });
if (requestStatus.state === "granted") {
console.log("权限已授予");
}
}
优点:
- 更加细致的权限控制
- 适合生产环境下动态管理权限
缺点:
- 增加代码复杂度
- 可能影响性能
3. 权限配置文件
Deno 2.0 引入了权限配置文件的机制,允许开发者提前定义权限配置并在运行时加载。这种方式适合复杂应用的权限管理。
示例配置文件 deno.json
:
{
"permissions": {
"read": ["./data"],
"net": ["example.com"],
"run": true
}
}
运行命令:
deno run --config deno.json app.ts
优点:
- 适合生产环境和复杂项目
- 权限集中管理,维护方便
缺点:
- 增加了配置的复杂性
- 不适合快速调试场景
权限授予方式对比总结
授予方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
命令行参数 | 简单直观,快速调试 | 维护不便,复杂应用不适合 | 开发、快速调试 |
权限 API | 动态控制,精细粒度 | 增加代码复杂性,可能影响性能 | 生产环境动态授权 |
权限配置文件 | 权限集中管理,适合复杂项目 | 配置复杂,调试不便 | 复杂应用,生产环境 |
四、触发权限的代码与运行示例
以下简单示例展示如何在不同场景下触发 Deno 的权限机制。该示例包括文件读取、网络请求和运行子进程。
代码示例:
// 尝试读取文件
try {
const fileContent = await Deno.readTextFile("./secret.txt");
console.log(fileContent);
} catch (error) {
console.error("读取文件失败:", error);
}
// 尝试发起网络请求
try {
const response = await fetch("https://deno.land");
const text = await response.text();
console.log(text);
} catch (error) {
console.error("网络请求失败:", error);
}
// 尝试运行子进程
try {
const process = Deno.run({
cmd: ["echo", "Hello from Deno!"] });
await process.status();
} catch (error) {
console.error("运行子进程失败:", error);
}
运行命令:
deno run --allow-read --allow-net --allow-run example.ts
通过这段代码,开发者可以观察到在未授予相应权限时,Deno 会抛出错误,提示缺少必要的权限。
五、总结
Deno 2.0 的权限系统是其安全架构的核心,通过默认的权限隔离和显式的权限授予机制,为前端全栈开发者提供了更高的安全性和灵活性。在不同场景下,开发者可以根据需求选择命令行参数、权限 API 或配置文件等不同方式来授予和管理权限。通过合理利用这些机制,可以确保应用的安全性和稳定性。