Deno 權(quán)限 API

2020-09-22 17:21 更新

Permission APIs

這是一個不穩(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)行交互的方法。

權(quá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)限

檢查一個權(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)

權(quán)限狀態(tài)可以是以下之一:

  • granted (已授予)
  • prompt(提示)
  • denied(已禁止)

從 CLI 授予的權(quán)限是 { state: "granted" },其他未授予的權(quán)限默認(rèn)為 { state: "prompt" },明確禁止的權(quán)限是 { state: "denied" }。

相關(guān)說明在 請求權(quán)限

權(quán)限強(qiáng)度

檢查權(quán)限 中第二個查詢的直觀理解:讀取權(quán)限授予到 /foo,/foo/bar 包含在 /foo 中,所以允許讀取 /foo/bar。

我們也可以說 desc1 強(qiáng)于 desc2。這意味著對于任意從 CLI 授予的權(quán)限:

  1. 如果 desc1 狀態(tài)為 { state: "granted" },那么 desc2 也是。
  2. 如果 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" };

請求權(quán)限

通過 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)限

將權(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" }
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號