NuGet 伺服器實作指南
在某些情況下,您可能想要實作自己的 NuGet 套件摘要。 有許多 現有的實作 可讓您以各種方式裝載自己的摘要,但官方 NuGet 用戶端軟體和套件摘要之間的通訊協定記載可讓您從頭開始建置自己的摘要實作。
通訊協定會隨著時間而演進,本指南的目標是想要或已經實作NuGet 套件伺服器的通訊協定。
自 2015 年 NuGet V3 通訊協定的初始版本以來,NuGet 已演進為開發人員提供更豐富的體驗,這需要套件存放庫執行額外的工作,以提供其套件取用者的額外價值,而不只是從託管套件進行元數據,並以各種形式傳回元數據。 例如,搜尋和套件元數據端點只包含 nupkg nuspec 檔案中找到的元數據。
請注意,本指南著重於 NuGet V3 通訊協定,因為 V2 通訊協定基本上未記載,而且自 2015 年以來,NuGet 用戶端和伺服器通訊的建議通訊協定是 V3 通訊協定。 如需詳細資訊,請參閱通訊協定版本控制。
年表
為了協助現有 NuGet 存放庫的作者掌握 NuGet 的最新功能,以下是文件其餘部分所提及相關功能的時序。
Year | 功能 |
---|---|
2013 | 說明如何在 nuget.org 上管理套件擁有者的部落格文章,釐清網站上顯示的擁有者是有權上傳新版本的帳戶,因此owners 會忽略套件中的元數據 |
2017 | 已新增 verified 至 SearchQueryService 回應。 |
語意版本設定 2.0.0 支援 | |
2018 | 內嵌授權 |
2019 | 內嵌圖示 |
中的 RegistrationBaseUrl 套件取代 (套件元資料資源) |
|
2020 | 中的 RegistrationsBaseUrl 套件弱點資訊 (套件元數據資源) |
已將查詢參數新增 packageTypes 至 SearchQueryService 要求 |
|
2021 | 內嵌自述檔 |
2023 | 預先驗證已驗證的要求 VulnerabilityInfo 資源 |
擁有者欄位
請考慮兩個 套件指令清單檔 (.nuspec
) 欄位與 <authors>
<owners>
。
封裝第三方內容的套件作者通常會將第三方名稱放在 <authors>
欄位中。
欄位 <owners>
的目的是表示誰在存放庫上發佈套件,因此在封裝問題或問題時應該連絡誰。
這在 2013 年的部落格文章中說明,因此<owners>
該欄位在檔案中.nuspec
被視為已過時。
如果套件的指令清單包含此元數據,則應該忽略它。
請勿在搜尋資源或封裝元數據資源 JSON 回應中的 屬性中owners
傳回檔案<owners>
欄位的值.nuspec
。
如果您的存放庫具有個別套件許可權,建議您報告有權在元數據中發佈新版本的 owner
帳戶,以搜尋和封裝元數據資源 JSON 回應。
verified
搜尋回應欄位
當新的欄位verified
設定為 true
時,Visual Studio 的 封裝管理員 UI 會顯示搜尋服務結果中套件旁的藍色複選標記。
NuGet.org 使用這個搭配套件前置詞數據(伺服器端數據,不是 NuGet API 的一部分),因此只有在擁有套件上傳套件的帳戶時,才會向客戶顯示此複選標記。
例如,只有在 microsoft 帳戶在 nuget.org 上擁有套件時,才會驗證具有前置詞microsoft.*
的任何套件。在實作保留前置詞之前,上傳套件標識符開頭microsoft.
為的套件的任何人員,都不會有此已驗證的複選標記。
NuGet.org 也允許前置詞不為獨佔,因此任何人都可以上傳下的 Contoso.ToolWithPlugins.Community.*
套件,但不會取得已驗證的複選標記。
語意版本設定 2.0.0 支援
NuGet 支援 與 Semantic Version 之間的System.Version
混合式,但在 2017 年已新增語意版本 2.0.0 的支援。
因此,將版本傳回至低於 3.6.0 之用戶端版本的 NuGet API 資源不得傳回使用 Semantic 2.0.0 功能與 Semantic Versioning 1.0.0 不相容的套件。
這兩個版本之間最重要的差異是發行前卷標和元數據字串。
語意版本設定 1.0.0 規格會[0-9A-Za-z-]
針對發行前版本標籤中只允許的字元,提供作為範例正則表達式字串,而且不支援元數據字串。
語意版本設定 2.0.0 規格可讓發行前版本標識碼以.
字元分隔(並禁止數值標識元具有前置零),並允許在 之後+
新增建置元數據。
在 套件元數據資源 (RegistrationsBaseUrl
)中,低於 3.6.0 的資源版本只能傳回符合 的套件。NET 的 System.Version
或語意版本設定 1.0.0。
這表示這些用戶端版本只符合語意版本設定 2.0.0 的套件。
同樣地, 搜尋查詢服務 (SearchQueryService
) 和 自動完成服務 (SearchAutocompleteService
) 也新增 &semVerLevel={version}
了查詢參數。
遺失時 semVerLevel
,假設 值為 1.0.0
。
如同套件元數據資源,當值低於 2.0.0 時 semVerLevel
,不得傳回版本僅與 Semantic Versioning 2.0.0 相容的套件。
內嵌檔案
套件 圖示、 授權和 自述檔 可以內嵌在套件中(且建議使用)。
這些檔案需要 URL 端點、擷取並放在靜態檔伺服器上,或動態擷取要求檔案的 .nupkg
URL,以便檢視它們而不需下載整個 nupkg
。
如果您的套件存放庫提供套件瀏覽和檢視套件詳細數據,您可以使用 URL 來顯示客戶網站上的內嵌內容。
最後,套件元數據資源和搜尋資源必須包含 JSON 回應的iconUrl
、 licenseUrl
和/或 readmeUrl
屬性中的託管 URL。
套件(.nupkg
檔案)不得修改,因為用戶端功能(鎖定檔案和已簽署的套件)會在套件遭到竄改時偵測修改。
請注意,授權可以是SPDX運算式或內嵌檔案(但不能同時包含兩者)。
在搜尋和套件元數據結果中表示時,使用授權表達式的套件可以 licenseUrl
設定為授權表達式、URL 編碼,並附加至 結尾 https://licenses.nuget.org/。
例如: https://licenses.nuget.org/Apache-2.0 。
NuGet.org 伺服器小組有關於 licenses.nuget.org 的其他檔。
已知的弱點和淘汰數據
套件元資料資源 (RegistrationsBaseUrl
)
套件 元數據資源 可以包含 取代 和 弱點 資訊。 這可讓客戶流覽 Visual Studio 封裝管理員 使用者介面中的套件,或其他 IDE 中的對等專案,以收到重要安全性或維護問題的通知。
如果您的套件存放庫是來自另一個存放庫的「向上來源」套件,若要在您自己的摘要中鏡像套件,建議您定期檢查原始來源是否有取代或弱點數據,並鏡像您自己的存放庫中的元數據。
如果您的套件存放庫是特別從 nuget.org 來源,只要保留上次檢查的狀態(「數據指標」,您就可以使用Catalog
資源有效率地檢查是否有套件正在鏡像的套件更新,而不需要從上游摘要下載大量套件元數據 JSON 檔案。
有 一個指南,說明如何搭配範例程式代碼使用目錄資源 ,以協助您開始使用。
已知的弱點資料庫 (VulnerabilityInfo
)
為了在套件還原期間提供高效能弱點掃描,NuGet 會從VulnerabilityInfo
資源下載已知弱點的完整清單。
Nuget.org 提供 GitHub Advisories 資料庫中所有 GitHub 檢閱諮詢的弱點數據,其中包含未裝載於 nuget.org 上的套件。
如果您的套件存放庫裝載第一方套件,而且您想要使用自己的摘要將弱點資訊提供給客戶,但尚未透露任何套件弱點,您應該提供一或多個弱點頁面的弱點索引,其內容為空的 JSON 數位列 ([]
)。
如果您的套件存放庫是要由應用程式作為預設存放庫使用(而不是 nuget.org),您可以使用 nuget.org 的弱點數據。
其中一個選項是在服務索引中使用 nuget.org 的弱點索引 URL。
另一個選項是定期檢查 nuget.org 的 VulnerabilityInfo
索引,並將任何變更的頁面下載到本機鏡像。
packageTypes
搜尋查詢
.NET CLI 允許使用 dotnet tool search
命令搜尋 .NET 工具套件。
這是藉由將查詢參數新增 &packageTypes={value}
至 搜尋查詢資源來實作,該資源會從封裝的 .nuspec
檔案 <packageTypes>
欄位讀取值。
已驗證摘要的 URL 結構
如 NuGet API 概觀中所述,所有 NuGet 伺服器通訊的起始 URL 是服務索引。
本檔包含 NuGet 用戶端將查詢之所有其他資源的 URL。
從 NuGet 6.7 起(Visual Studio 和 MSBuild 17.7 和 .NET SDK 7.0.400),NuGet 會使用 。NET 的 HttpClientHandler.PreAuthenticate
,只有在後續 URL 位於先前已驗證之 URL 的相同虛擬目錄或子目錄中時,才會避免匿名 HTTP 要求。
這可大幅減少傳送至伺服器的未驗證 HTTP 要求數目,因此會減少您的伺服器工作負載。
以下列出一些範例:
URL | PreAuthenticate 嗎? |
---|---|
https://pkgs.contoso.com/nuget/v3/feed/index.json | N/A,這是服務索引。 |
https://pkgs.contoso.com/nuget/v3/search | 否,不在與服務索引相同的或子目錄中。 |
https://search.pkgs.contoso.com/nuget/v3/feed/ | 否,不在與服務索引相同的主機名上。 |
https://pkgs.contoso.com/nuget/v3/feed/search | 是,在與服務索引相同的目錄中。 |
https://pkgs.contoso.com/nuget/v3/registration/ | 否,不在服務索引的子目錄中。 |
https://pkgs.contoso.com/nuget/v3/feed/registration/ | 是,在服務索引的子目錄中。 |
https://pkgs.contoso.com/nuget/v3/{guid}/registration/ | 請參閱下文 |
在最後一個範例中,伺服器可能有標準名稱(在此範例中為 guid)名稱,而且有一或多個別名。
如果在非標準 URL 上驗證服務索引要求(在我們的範例 feed
中為「易記」名稱),則不,標準 URL 下資源的任何要求都不會符合 HttpClientHandler
的規則 PreAuthenticate
。
不過,如果非標準 URL 是標準 URL 的 HTTP 重新導向, https://pkgs.contoso.com/nuget/v3/{guid}/index.json則此 URL 將會用於 HttpClientHandler
認證快取中。
在此情況下,由於重新導向,服務索引的每個要求都會有額外的延遲。
雖然 NuGet 的 V3 API 設計成在靜態檔伺服器上運作,但搜尋資源是一律需要動態 Web 服務來處理要求的例外狀況。
如果您想要在不同的伺服器上裝載搜尋,或確實裝載任何其他 NuGet API 資源,才能受益於 HttpClientHandler
的 PreAuthenticate
,您必須使用反向 Proxy 來確保服務索引中的所有客戶面向 URL 都符合「相同或子目錄」規則。