這是一個不穩(wěn)定的 Deno API。 更多信息請查閱 穩(wěn)定性
權(quán)限是在運(yùn)行 deno
命令時從 CLI 授予的。用戶代碼通常會假定自己擁有一組必需的權(quán)限,但是在執(zhí)行過程中不能保證 已授予 的權(quán)限集合中包含所需權(quán)限。
在某些情況下,具有容錯能力的程序需要一種在運(yùn)行時與權(quán)限系統(tǒng)進(jìn)行交互的方法。
在 CLI 中,/foo/bar
的讀取權(quán)限表示為 --allow-read=/foo/bar
。
在運(yùn)行時,它表示為以下形式:
const desc = { name: "read", path: "/foo/bar" };
其他示例:
// 全局寫入權(quán)限
const desc1 = { name: "write" };
// `$PWD/foo/bar` 的寫入權(quán)限
const desc2 = { name: "write", path: "foo/bar" };
// 全局網(wǎng)絡(luò)權(quán)限
const desc3 = { name: "net" };
// 訪問 127.0.0.1:8000 的網(wǎng)絡(luò)權(quán)限
const desc4 = { name: "net", url: "127.0.0.1:8000" };
// 高精度計時權(quán)限
const desc5 = { name: "hrtime" };
檢查一個權(quán)限是否已被授予:
// deno run --unstable --allow-read=/foo main.ts
const desc1 = { name: "read", path: "/foo" };
console.log(await Deno.permissions.query(desc1));
// PermissionStatus { state: "granted" }
const desc2 = { name: "read", path: "/foo/bar" };
console.log(await Deno.permissions.query(desc2));
// PermissionStatus { state: "granted" }
const desc3 = { name: "read", path: "/bar" };
console.log(await Deno.permissions.query(desc3));
// PermissionStatus { state: "prompt" }
權(quán)限狀態(tài)可以是以下之一:
從 CLI 授予的權(quán)限是 { state: "granted" }
,其他未授予的權(quán)限默認(rèn)為 { state: "prompt" }
,明確禁止的權(quán)限是 { state: "denied" }
。
相關(guān)說明在 請求權(quán)限。
檢查權(quán)限 中第二個查詢的直觀理解:讀取權(quán)限授予到 /foo
,/foo/bar
包含在 /foo
中,所以允許讀取 /foo/bar
。
我們也可以說 desc1
強(qiáng)于 desc2
。這意味著對于任意從 CLI 授予的權(quán)限:
desc1
狀態(tài)為 { state: "granted" }
,那么 desc2
也是。desc2
狀態(tài)為 { state: "denied" }
,那么 desc1
也是。更多示例:
const desc1 = { name: "write" };
// 強(qiáng)于
const desc2 = { name: "write", path: "/foo" };
const desc3 = { name: "net" };
// 強(qiáng)于
const desc4 = { name: "net", url: "127.0.0.1:8000" };
通過 CLI 提示來請求一個未授予的權(quán)限:
// deno run --unstable main.ts
const desc1 = { name: "read", path: "/foo" };
const status1 = await Deno.permissions.request(desc1);
// ?? Deno requests read access to "/foo". Grant? [g/d (g = grant, d = deny)] g
console.log(status1);
// PermissionStatus { state: "granted" }
const desc2 = { name: "read", path: "/bar" };
const status2 = await Deno.permissions.request(desc2);
// ?? Deno requests read access to "/bar". Grant? [g/d (g = grant, d = deny)] d
console.log(status2);
// PermissionStatus { state: "denied" }
如果當(dāng)前權(quán)限狀態(tài)是 "prompt",用戶終端中會出現(xiàn)一個提示來詢問用戶是否要授權(quán)。desc1
的授權(quán)請求通過,所以新的狀態(tài)會返回,程序繼續(xù)執(zhí)行。desc2
的授權(quán)被禁止,權(quán)限狀態(tài)會從 "prompt" 降級為 "denied"。
如果當(dāng)前權(quán)限狀態(tài)已經(jīng)是 "granted" 或 "denied",請求將表現(xiàn)為一個檢查,直接返回當(dāng)前權(quán)限狀態(tài),這會阻止多余的提示。
將權(quán)限狀態(tài)從 "granted" 降級為 "prompt":
// deno run --unstable --allow-read=/foo main.ts
const desc = { name: "read", path: "/foo" };
console.log(await Deno.permissions.revoke(desc));
// PermissionStatus { state: "prompt" }
然而,當(dāng)嘗試放棄 一部分 權(quán)限時,會發(fā)生什么?
// deno run --unstable --allow-read=/foo main.ts
const desc = { name: "read", path: "/foo/bar" };
console.log(await Deno.permissions.revoke(desc));
// PermissionStatus { state: "granted" }
它不會被放棄。
想象 Deno 存儲了一個 明確授予的權(quán)限描述符 的內(nèi)部集合。在 CLI 中指定 --allow-read=/foo,/bar
會把這一集合初始化為:
[
{ name: "read", path: "/foo" },
{ name: "read", path: "/bar" },
];
一個運(yùn)行時授權(quán) { name: "write", path: "/foo" }
會更新這個集合:
[
{ name: "read", path: "/foo" },
{ name: "read", path: "/bar" },
{ name: "write", path: "/foo" },
];
Deno 的權(quán)限撤銷算法將所有不強(qiáng)于參數(shù)權(quán)限描述符的元素從集合中移除。
要確保 desc
不再有效,您需要傳遞一個參數(shù)權(quán)限描述符,它必須 強(qiáng)于 集合中所有 強(qiáng)于 desc
的 顯式授予的權(quán)限描述符。
// deno run --unstable --allow-read=/foo main.ts
const desc = { name: "read", path: "/foo/bar" };
console.log(await Deno.permissions.revoke(desc)); // 無效
// PermissionStatus { state: "granted" }
const strongDesc = { name: "read", path: "/foo" };
await Deno.permissions.revoke(strongDesc); // 正確
console.log(await Deno.permissions.query(desc));
// PermissionStatus { state: "prompt" }
更多建議: