[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Fauth":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Fauth":1052,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Fauth":1072},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":1048,"stem":1049,"id":1050,"extension":1051},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Fauth","权限模型","Deno 默认在安全的沙盒环境中执行任何代码——无论是你的主程序还是第三方依赖，都没有文件、网络、环境变量或子进程的访问权限。只有通过 命令行标志显式授予 的权限才能被使用。","技能小册",[12,13],"deno","auth","2021-04-01",false,{"type":17,"value":18,"toc":1031},"minimark",[19,22,27,40,45,161,227,231,309,313,320,488,499,503,546,550,559,623,626,630,636,654,664,760,764,828,835,838,893,896,923,926,956,960,973,976,1027],[20,21,8],"h1",{"id":8},[23,24,26],"h2",{"id":25},"deno-权限模型核心安全特性","Deno 权限模型（核心安全特性）",[28,29,30,31,35,36,39],"p",{},"Deno 默认在安全的",[32,33,34],"strong",{},"沙盒","环境中执行任何代码——无论是你的主程序还是第三方依赖，都没有文件、网络、环境变量或子进程的访问权限。只有通过 ",[32,37,38],{},"命令行标志显式授予"," 的权限才能被使用。",[41,42,44],"h3",{"id":43},"一权限标志速查表","一、权限标志速查表",[46,47,48,61],"table",{},[49,50,51],"thead",{},[52,53,54,58],"tr",{},[55,56,57],"th",{},"权限标志",[55,59,60],{},"说明",[62,63,64,79,89,102,116,134,144],"tbody",{},[52,65,66,73],{},[67,68,69],"td",{},[70,71,72],"code",{},"--allow-read",[67,74,75,76],{},"允许读取文件系统。可以限定路径：",[70,77,78],{},"--allow-read=\u002Fetc,\u002Ftmp",[52,80,81,86],{},[67,82,83],{},[70,84,85],{},"--allow-write",[67,87,88],{},"允许写入文件系统。同样可限定写入目录",[52,90,91,96],{},[67,92,93],{},[70,94,95],{},"--allow-net",[67,97,98,99],{},"允许网络访问。可限定域名或 IP：",[70,100,101],{},"--allow-net=api.example.com,localhost",[52,103,104,109],{},[67,105,106],{},[70,107,108],{},"--allow-env",[67,110,111,112,115],{},"允许读取环境变量（默认无法访问 ",[70,113,114],{},"process.env","）",[52,117,118,123],{},[67,119,120],{},[70,121,122],{},"--allow-run",[67,124,125,126,129,130,133],{},"允许运行子进程（现应使用 ",[70,127,128],{},"new Deno.Command()","；",[70,131,132],{},"Deno.run()"," 已在 Deno 2 中软移除，仅保留实现、类型已删除）",[52,135,136,141],{},[67,137,138],{},[70,139,140],{},"--allow-ffi",[67,142,143],{},"允许调用外部函数接口（Foreign Function Interface）",[52,145,146,155],{},[67,147,148,151,152],{},[70,149,150],{},"-A"," 或 ",[70,153,154],{},"--allow-all",[67,156,157,160],{},[32,158,159],{},"授予所有权限","（仅在开发 \u002F 测试原型时使用，生产环境不推荐）",[162,163,164,185,216],"blockquote",{},[28,165,166,172,173,176,177,180,181,184],{},[32,167,168,171],{},[70,169,170],{},"--deny-*"," 标志","：在已 ",[70,174,175],{},"--allow-*"," 的前提下，可进一步拒绝特定路径或域名；",[70,178,179],{},"deny"," 优先于 ",[70,182,183],{},"allow","。例如：",[186,187,192],"pre",{"className":188,"code":189,"language":190,"meta":191,"style":191},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","deno run --allow-net --deny-net=github.com,jsr.io script.ts\n","bash","",[70,193,194],{"__ignoreMap":191},[195,196,199,202,206,210,213],"span",{"class":197,"line":198},"line",1,[195,200,12],{"class":201},"sbgvK",[195,203,205],{"class":204},"s_sjI"," run",[195,207,209],{"class":208},"stzsN"," --allow-net",[195,211,212],{"class":208}," --deny-net=github.com,jsr.io",[195,214,215],{"class":204}," script.ts\n",[28,217,218,219,226],{},"详见 ",[220,221,225],"a",{"href":222,"rel":223},"https:\u002F\u002Fdocs.deno.com\u002Fruntime\u002Ffundamentals\u002Fsecurity\u002F#permissions",[224],"nofollow","Permissions","。",[41,228,230],{"id":229},"二常用命令示例","二、常用命令示例",[186,232,234],{"className":188,"code":233,"language":190,"meta":191,"style":191},"# 允许读取文件（无限制） + 网络访问\ndeno run --allow-read --allow-net server.ts\n\n# 限制文件读取路径仅 \u002Fdata 目录，网络仅允许访问 api.example.com\ndeno run --allow-read=\u002Fdata --allow-net=api.example.com main.ts\n\n# 授予所有权限（快速原型，非生产）\ndeno run -A main.ts\n",[70,235,236,242,257,264,270,286,291,297],{"__ignoreMap":191},[195,237,238],{"class":197,"line":198},[195,239,241],{"class":240},"sutJx","# 允许读取文件（无限制） + 网络访问\n",[195,243,245,247,249,252,254],{"class":197,"line":244},2,[195,246,12],{"class":201},[195,248,205],{"class":204},[195,250,251],{"class":208}," --allow-read",[195,253,209],{"class":208},[195,255,256],{"class":204}," server.ts\n",[195,258,260],{"class":197,"line":259},3,[195,261,263],{"emptyLinePlaceholder":262},true,"\n",[195,265,267],{"class":197,"line":266},4,[195,268,269],{"class":240},"# 限制文件读取路径仅 \u002Fdata 目录，网络仅允许访问 api.example.com\n",[195,271,273,275,277,280,283],{"class":197,"line":272},5,[195,274,12],{"class":201},[195,276,205],{"class":204},[195,278,279],{"class":208}," --allow-read=\u002Fdata",[195,281,282],{"class":208}," --allow-net=api.example.com",[195,284,285],{"class":204}," main.ts\n",[195,287,289],{"class":197,"line":288},6,[195,290,263],{"emptyLinePlaceholder":262},[195,292,294],{"class":197,"line":293},7,[195,295,296],{"class":240},"# 授予所有权限（快速原型，非生产）\n",[195,298,300,302,304,307],{"class":197,"line":299},8,[195,301,12],{"class":201},[195,303,205],{"class":204},[195,305,306],{"class":208}," -A",[195,308,285],{"class":204},[41,310,312],{"id":311},"三动态权限请求运行时","三、动态权限请求（运行时）",[28,314,315,316,319],{},"可以用 ",[70,317,318],{},"Deno.permissions.request()"," API 在代码中询问用户是否授予某个权限：",[186,321,325],{"className":322,"code":323,"language":324,"meta":191,"style":191},"language-typescript shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F 请求网络权限\nconst status = await Deno.permissions.request({ name: \"net\" });\nif (status.state === \"granted\") {\n  await fetch(\"https:\u002F\u002Fdeno.land\");\n} else {\n  console.error(\"网络权限未授予\");\n}\n","typescript",[70,326,327,332,399,428,449,460,483],{"__ignoreMap":191},[195,328,329],{"class":197,"line":198},[195,330,331],{"class":240},"\u002F\u002F 请求网络权限\n",[195,333,334,338,342,346,350,354,358,361,363,367,370,373,377,380,384,387,390,393,396],{"class":197,"line":244},[195,335,337],{"class":336},"sbsja","const",[195,339,341],{"class":340},"s_hVV"," status",[195,343,345],{"class":344},"smGrS"," =",[195,347,349],{"class":348},"sVHd0"," await",[195,351,353],{"class":352},"su5hD"," Deno",[195,355,357],{"class":356},"sP7_E",".",[195,359,360],{"class":352},"permissions",[195,362,357],{"class":356},[195,364,366],{"class":365},"sGLFI","request",[195,368,369],{"class":352},"(",[195,371,372],{"class":356},"{",[195,374,376],{"class":375},"skxfh"," name",[195,378,379],{"class":356},":",[195,381,383],{"class":382},"sjJ54"," \"",[195,385,386],{"class":204},"net",[195,388,389],{"class":382},"\"",[195,391,392],{"class":356}," }",[195,394,395],{"class":352},")",[195,397,398],{"class":356},";\n",[195,400,401,404,407,409,412,415,417,420,422,425],{"class":197,"line":259},[195,402,403],{"class":348},"if",[195,405,406],{"class":352}," (status",[195,408,357],{"class":356},[195,410,411],{"class":352},"state ",[195,413,414],{"class":344},"===",[195,416,383],{"class":382},[195,418,419],{"class":204},"granted",[195,421,389],{"class":382},[195,423,424],{"class":352},") ",[195,426,427],{"class":356},"{\n",[195,429,430,433,436,438,440,443,445,447],{"class":197,"line":266},[195,431,432],{"class":348},"  await",[195,434,435],{"class":365}," fetch",[195,437,369],{"class":375},[195,439,389],{"class":382},[195,441,442],{"class":204},"https:\u002F\u002Fdeno.land",[195,444,389],{"class":382},[195,446,395],{"class":375},[195,448,398],{"class":356},[195,450,451,454,457],{"class":197,"line":272},[195,452,453],{"class":356},"}",[195,455,456],{"class":348}," else",[195,458,459],{"class":356}," {\n",[195,461,462,465,467,470,472,474,477,479,481],{"class":197,"line":288},[195,463,464],{"class":352},"  console",[195,466,357],{"class":356},[195,468,469],{"class":365},"error",[195,471,369],{"class":375},[195,473,389],{"class":382},[195,475,476],{"class":204},"网络权限未授予",[195,478,389],{"class":382},[195,480,395],{"class":375},[195,482,398],{"class":356},[195,484,485],{"class":197,"line":293},[195,486,487],{"class":356},"}\n",[28,489,490,491,494,495,498],{},"其他动作包括 ",[70,492,493],{},"query","（查询当前状态）、",[70,496,497],{},"revoke","（撤销权限）。这个机制适合交互式 CLI 工具，让用户按需授权。",[41,500,502],{"id":501},"四安全模型的要点","四、安全模型的要点",[504,505,506,516,524,540],"ul",{},[507,508,509,512,513,515],"li",{},[32,510,511],{},"同等对待主程序和依赖","：Deno 不区分你的代码和第三方包，两者共享同一个权限集。换句话说，如果一个依赖被授予了 ",[70,514,95],{},"，它同样可以发起网络请求。",[507,517,518,521,522,226],{},[32,519,520],{},"最小权限原则","：建议只添加程序确实需要的标志，并使用路径\u002F域名限制，避免使用 ",[70,523,150],{},[507,525,526,529,530,533,534,536,537,539],{},[32,527,528],{},"无法动态提升权限","：",[70,531,532],{},"Deno.permissions.request"," 只能降级或询问已在命令行声明范围的权限（例如 ",[70,535,95],{}," 开启了网络权限但未限定域名，则请求时会弹出确认框；如果根本没有 ",[70,538,95],{},"，则请求会被直接拒绝）。",[507,541,542,545],{},[32,543,544],{},"生产部署","：通常直接将必要的权限标志写入 Dockerfile 或启动脚本中，不依赖动态弹窗。",[41,547,549],{"id":548},"五精细化权限路径与域名限定","五、精细化权限：路径与域名限定",[28,551,552,553,555,556,558],{},"粗粒度的 ",[70,554,72],{},"\u002F",[70,557,95],{}," 已经比 Node 默认全放开安全得多，但更推荐进一步限定范围：",[186,560,562],{"className":188,"code":561,"language":190,"meta":191,"style":191},"# 只允许读取 .\u002Fconfig 与 .\u002Fdata 两个目录\ndeno run --allow-read=.\u002Fconfig,.\u002Fdata main.ts\n\n# 只允许访问指定的 API 域名，禁止访问其他任意网址\ndeno run --allow-net=api.example.com,cdn.example.com main.ts\n\n# 同时使用 allow 与 deny：允许所有网络，但明确拒绝内网地址段\ndeno run --allow-net --deny-net=169.254.169.254 fetch-external.ts\n",[70,563,564,569,580,584,589,600,604,609],{"__ignoreMap":191},[195,565,566],{"class":197,"line":198},[195,567,568],{"class":240},"# 只允许读取 .\u002Fconfig 与 .\u002Fdata 两个目录\n",[195,570,571,573,575,578],{"class":197,"line":244},[195,572,12],{"class":201},[195,574,205],{"class":204},[195,576,577],{"class":208}," --allow-read=.\u002Fconfig,.\u002Fdata",[195,579,285],{"class":204},[195,581,582],{"class":197,"line":259},[195,583,263],{"emptyLinePlaceholder":262},[195,585,586],{"class":197,"line":266},[195,587,588],{"class":240},"# 只允许访问指定的 API 域名，禁止访问其他任意网址\n",[195,590,591,593,595,598],{"class":197,"line":272},[195,592,12],{"class":201},[195,594,205],{"class":204},[195,596,597],{"class":208}," --allow-net=api.example.com,cdn.example.com",[195,599,285],{"class":204},[195,601,602],{"class":197,"line":288},[195,603,263],{"emptyLinePlaceholder":262},[195,605,606],{"class":197,"line":293},[195,607,608],{"class":240},"# 同时使用 allow 与 deny：允许所有网络，但明确拒绝内网地址段\n",[195,610,611,613,615,617,620],{"class":197,"line":299},[195,612,12],{"class":201},[195,614,205],{"class":204},[195,616,209],{"class":208},[195,618,619],{"class":208}," --deny-net=169.254.169.254",[195,621,622],{"class":204}," fetch-external.ts\n",[28,624,625],{},"最后一个例子在防止 SSRF（服务端请求伪造）攻击时很实用：即使代码存在漏洞被诱导访问任意 URL，也无法访问云厂商的内网元数据服务。",[41,627,629],{"id":628},"六测试中的权限控制","六、测试中的权限控制",[28,631,632,635],{},[70,633,634],{},"deno test"," 同样遵循权限模型，测试文件默认无权限，需要什么权限就显式声明，这能帮助及早发现测试对外部资源的隐式依赖：",[186,637,639],{"className":188,"code":638,"language":190,"meta":191,"style":191},"deno test --allow-net=localhost:8080 --allow-env=NODE_ENV\n",[70,640,641],{"__ignoreMap":191},[195,642,643,645,648,651],{"class":197,"line":198},[195,644,12],{"class":201},[195,646,647],{"class":204}," test",[195,649,650],{"class":208}," --allow-net=localhost:8080",[195,652,653],{"class":208}," --allow-env=NODE_ENV\n",[28,655,656,657,660,661,663],{},"也可以在测试代码中用 ",[70,658,659],{},"Deno.test"," 的 ",[70,662,360],{}," 选项为单个测试单独声明所需权限，避免整份测试文件的权限范围被无意放大：",[186,665,667],{"className":322,"code":666,"language":324,"meta":191,"style":191},"Deno.test({\n  name: \"读取配置文件\",\n  permissions: { read: [\".\u002Ffixtures\u002Fconfig.json\"] },\n  fn() {\n    \u002F\u002F 仅在此测试内生效的只读权限\n  },\n});\n",[70,668,669,683,700,731,742,747,752],{"__ignoreMap":191},[195,670,671,674,676,679,681],{"class":197,"line":198},[195,672,673],{"class":352},"Deno",[195,675,357],{"class":356},[195,677,678],{"class":365},"test",[195,680,369],{"class":352},[195,682,427],{"class":356},[195,684,685,688,690,692,695,697],{"class":197,"line":244},[195,686,687],{"class":375},"  name",[195,689,379],{"class":356},[195,691,383],{"class":382},[195,693,694],{"class":204},"读取配置文件",[195,696,389],{"class":382},[195,698,699],{"class":356},",\n",[195,701,702,705,707,710,713,715,718,720,723,725,728],{"class":197,"line":259},[195,703,704],{"class":375},"  permissions",[195,706,379],{"class":356},[195,708,709],{"class":356}," {",[195,711,712],{"class":375}," read",[195,714,379],{"class":356},[195,716,717],{"class":352}," [",[195,719,389],{"class":382},[195,721,722],{"class":204},".\u002Ffixtures\u002Fconfig.json",[195,724,389],{"class":382},[195,726,727],{"class":352},"] ",[195,729,730],{"class":356},"},\n",[195,732,733,737,740],{"class":197,"line":266},[195,734,736],{"class":735},"sVXei","  fn",[195,738,739],{"class":356},"()",[195,741,459],{"class":356},[195,743,744],{"class":197,"line":272},[195,745,746],{"class":240},"    \u002F\u002F 仅在此测试内生效的只读权限\n",[195,748,749],{"class":197,"line":288},[195,750,751],{"class":356},"  },\n",[195,753,754,756,758],{"class":197,"line":293},[195,755,453],{"class":356},[195,757,395],{"class":352},[195,759,398],{"class":356},[41,761,763],{"id":762},"七与-nodejs-权限模型的对比","七、与 Node.js 权限模型的对比",[46,765,766,778],{},[49,767,768],{},[52,769,770,773,775],{},[55,771,772],{},"维度",[55,774,673],{},[55,776,777],{},"Node.js",[62,779,780,791,802,817],{},[52,781,782,785,788],{},[67,783,784],{},"默认权限",[67,786,787],{},"默认全部拒绝",[67,789,790],{},"默认进程级全部允许",[52,792,793,796,799],{},[67,794,795],{},"第三方依赖",[67,797,798],{},"与主程序共享同一权限集，可被限制",[67,800,801],{},"依赖天然拥有与主程序相同的能力，无原生隔离",[52,803,804,807,810],{},[67,805,806],{},"授权方式",[67,808,809],{},"命令行标志 \u002F 运行时动态请求",[67,811,812,813,816],{},"无内建机制，需依赖第三方沙箱库（如 ",[70,814,815],{},"vm2","，且历史上出现过逃逸漏洞）",[52,818,819,822,825],{},[67,820,821],{},"适合场景",[67,823,824],{},"运行不完全信任的第三方代码、插件系统",[67,826,827],{},"传统全信任的服务端应用",[28,829,830,831,834],{},"这也是为什么 Deno 常被用于",[32,832,833],{},"运行用户提交的脚本","（在线代码练习平台、Serverless 函数网关等）场景——权限模型天然提供了一层沙箱。",[23,836,837],{"id":837},"常见坑",[504,839,840,860,872,878],{},[507,841,842,529,849,851,852,854,855,857,858,226],{},[32,843,844,845,848],{},"以为 ",[70,846,847],{},"--deny-net"," 能单独生效",[70,850,179],{}," 只在对应的 ",[70,853,183],{}," 已经放开的前提下“做减法”，如果本身没有 ",[70,856,95],{},"，网络请求依旧会被直接拒绝，不需要也不应该额外加 ",[70,859,179],{},[507,861,862,868,869,871],{},[32,863,864,865,867],{},"开发环境长期使用 ",[70,866,150],{}," 导致习惯性带入生产","：本地为了方便加了 ",[70,870,150],{},"，上线脚本直接复制粘贴，权限收紧的收益就完全丧失了。",[507,873,874,877],{},[32,875,876],{},"以为权限是按“模块”而不是按“进程”授予","：所有代码（主程序 + 全部依赖）共享同一份权限集合，无法只给某个第三方包单独限权（除非拆分为独立子进程）。",[507,879,880,529,886,889,890,892],{},[32,881,882,883,885],{},"忘记 ",[70,884,108],{}," 也可以限定具体变量名",[70,887,888],{},"--allow-env=PATH,HOME"," 比无限制的 ",[70,891,108],{}," 更安全，很多人不知道该标志同样支持逗号分隔的白名单。",[23,894,895],{"id":895},"最佳实践",[897,898,899,910,913,920],"ol",{},[507,900,901,902,904,905,907,908,226],{},"遵循",[32,903,520],{},"：先不加任何权限运行，根据报错逐一补充需要的 ",[70,906,175],{},"，而不是一开始就 ",[70,909,150],{},[507,911,912],{},"涉及网络、文件的标志尽量加上具体的域名\u002F路径限定，而不是完全开放。",[507,914,915,916,919],{},"面向不受信任代码（插件、用户脚本）的场景，考虑结合 ",[70,917,918],{},"Deno.Command","\u002F子进程 + 更严格的权限组合，把风险隔离到独立进程。",[507,921,922],{},"在 CI 与生产 Dockerfile 中把最终确定的权限标志固化下来，作为该服务“需要哪些资源”的活文档。",[23,924,925],{"id":925},"延伸阅读",[504,927,928,935,942],{},[507,929,930,934],{},[220,931,933],{"href":932},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Fbase","Deno 基础","：权限模型是 Deno 与 Node 最核心的差异点之一。",[507,936,937,941],{},[220,938,940],{"href":939},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Finstall","安装与环境","：安装完成后即可开始体验权限提示。",[507,943,944,948,949,660,952,955],{},[220,945,947],{"href":946},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Finit","项目初始化与基础命令","：在 ",[70,950,951],{},"deno.json",[70,953,954],{},"tasks"," 中固化常用权限组合。",[41,957,959],{"id":958},"八总结","八、总结",[28,961,962,963,966,967,969,970,972],{},"Deno 的安全模型是其与 Node.js 最显著的差异之一。",[32,964,965],{},"默认拒绝，显式授权","的设计迫使开发者思考程序的真实需求，从而避免无意中引入安全漏洞。建议新人从 ",[70,968,72],{},"、",[70,971,95],{}," 等标志开始，逐步熟悉权限粒度控制。",[23,974,975],{"id":975},"参考文献",[46,977,978,987],{},[49,979,980],{},[52,981,982,985],{},[55,983,984],{},"资料",[55,986,60],{},[62,988,989,1001,1015],{},[52,990,991,998],{},[67,992,993],{},[220,994,997],{"href":995,"rel":996},"https:\u002F\u002Fdocs.deno.com\u002Fruntime\u002Ffundamentals\u002Fsecurity\u002F",[224],"Security",[67,999,1000],{},"官方权限说明",[52,1002,1003,1010],{},[67,1004,1005],{},[220,1006,1009],{"href":1007,"rel":1008},"https:\u002F\u002Fdocs.deno.com\u002Fapi\u002Fdeno\u002Fpermissions",[224],"Permissions API",[67,1011,1012],{},[70,1013,1014],{},"Deno.permissions",[52,1016,1017,1024],{},[67,1018,1019],{},[220,1020,1023],{"href":1021,"rel":1022},"https:\u002F\u002Fgithub.com\u002Fdenoland\u002Fsetup-deno",[224],"setup-deno",[67,1025,1026],{},"CI 中的权限与安装",[1028,1029,1030],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":191,"searchDepth":244,"depth":244,"links":1032},[1033,1042,1043,1044,1047],{"id":25,"depth":244,"text":26,"children":1034},[1035,1036,1037,1038,1039,1040,1041],{"id":43,"depth":259,"text":44},{"id":229,"depth":259,"text":230},{"id":311,"depth":259,"text":312},{"id":501,"depth":259,"text":502},{"id":548,"depth":259,"text":549},{"id":628,"depth":259,"text":629},{"id":762,"depth":259,"text":763},{"id":837,"depth":244,"text":837},{"id":895,"depth":244,"text":895},{"id":925,"depth":244,"text":925,"children":1045},[1046],{"id":958,"depth":259,"text":959},{"id":975,"depth":244,"text":975},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FDeno\u002Fauth","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FDeno\u002Fauth.md","md",{"items":1053},[1054,1056,1060,1062,1066,1070],{"path":932,"title":933,"description":1055,"category":10,"score":288},"Deno 是基于 V8 与 Rust 的 JavaScript\u002FTypeScript 运行时，由 Node.js 原作者 Ryan Dahl 发起。官方文档：docs.deno.com。与 Node、Bun 的对比见 运行时对比。",{"path":1057,"title":1058,"description":1059,"category":10,"score":288},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Ftools","内置工具链","Deno 提供了开箱即用的工具链，无需安装任何第三方依赖即可完成代码格式化、检查、测试、覆盖率、文档生成和基准测试等任务。",{"path":946,"title":947,"description":1061,"category":10,"score":288},"Deno 提供了开箱即用的项目管理工具集，无需额外配置即可初始化项目、运行脚本、执行代码片段等。",{"path":1063,"title":1064,"description":1065,"category":10,"score":288},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Fpackage","包管理与依赖","Deno 以 deno.json 管理项目（imports、tasks 等），依赖通过 URL、jsr:、npm: 解析并缓存到本地（默认 DENO_DIR），通常不需要像 Node 那样维护庞大的 node_modules 树。在需…",{"path":1067,"title":1068,"description":1069,"category":10,"score":288},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Fother","其他配置","Deno 默认禁止访问环境变量，以遵循最小权限原则。必须通过 --allow-env 标志显式开启。",{"path":939,"title":940,"description":1071,"category":10,"score":288},"Deno 提供了多种安装方式，覆盖主流操作系统。安装后需确保环境 PATH 正确，并可配置一些环境变量以控制行为。",{"series":1073,"title":12,"items":1074,"index":1092,"prev":1093,"next":1094},"booklet\u002Fend\u002Fdeno",[1075,1076,1078,1082,1084,1086,1088,1090],{"path":7,"title":8,"date":14,"pinned":15},{"path":932,"title":933,"date":1077,"pinned":15},"2026-06-01",{"path":1079,"title":1080,"date":1081,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fdeno\u002Fhttp","HTTP 服务器","2020-12-11",{"path":946,"title":947,"date":1083,"pinned":15},"2025-02-14",{"path":939,"title":940,"date":1085,"pinned":15},"2021-02-05",{"path":1067,"title":1068,"date":1087,"pinned":15},"2022-02-08",{"path":1063,"title":1064,"date":1089,"pinned":15},"2024-07-21",{"path":1057,"title":1058,"date":1091,"pinned":15},"2026-01-24",0,null,{"path":932,"title":933,"date":1077,"pinned":15}]