凭据提供者协议

本文档描述了构建 Cargo 凭据提供者的相关信息。有关设置或使用凭据提供者的信息,请参阅 注册表身份验证

当使用外部凭据提供者时,Cargo 使用通过标准输入/输出传递的单行 JSON 消息与凭据提供者进行通信。

Cargo 始终使用 --cargo-plugin 参数执行凭据提供者。这使凭据提供者可执行文件除了 Cargo 需要的功能外,还具有其他功能。额外的参数通过 args 字段包含在 JSON 中。

JSON 消息

本文档中的 JSON 消息为了便于阅读添加了换行符。实际的消息不能包含换行符。

凭据 Hello

  • 发送者:凭据提供者
  • 目的:用于在进程启动时标识支持的协议
{ "v":[1] }

Cargo 发送的请求将包含一个 v 字段,该字段设置为此处列出的版本之一。如果 Cargo 不支持凭据提供者提供的任何版本,它将发出错误并关闭凭据进程。

注册表信息

  • 发送者:Cargo 本身不是消息。作为 registry 字段包含在 Cargo 发送的所有消息中。
{ // Index URL of the registry "index-url":"https://github.com/rust-lang/crates.io-index", // Name of the registry in configuration (optional) "name": "crates-io", // HTTP headers received from attempting to access an authenticated registry (optional) "headers": ["WWW-Authenticate: cargo"] }

登录请求

  • 发送者:Cargo
  • 目的:收集并存储凭据
{ // Protocol version "v":1, // Action to perform: login "kind":"login", // Registry information (see Registry information) "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"}, // User-specified token from stdin or command line (optional) "token": "<the token value>", // URL that the user could visit to get a token (optional) "login-url": "http://registry-url/login", // Additional command-line args (optional) "args":[] }

如果设置了 token 字段,则凭据提供者应使用提供的令牌。如果未设置 token,则凭据提供者应提示用户输入令牌。

除了可以在配置中传递给凭据提供者的参数之外,cargo login 还支持通过 cargo login -- <其他参数> 传递其他命令行参数。这些额外的参数将包含在 args 字段中,位于 Cargo 配置中的任何参数之后。

读取请求

  • 发送者:Cargo
  • 目的:获取用于读取 crate 信息的凭据
{ // Protocol version "v":1, // Request kind: get credentials "kind":"get", // Action to perform: read crate information "operation":"read", // Registry information (see Registry information) "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"}, // Additional command-line args (optional) "args":[] }

发布请求

  • 发送者:Cargo
  • 目的:获取用于发布 crate 的凭据
{ // Protocol version "v":1, // Request kind: get credentials "kind":"get", // Action to perform: publish crate "operation":"publish", // Crate name "name":"sample", // Crate version "vers":"0.1.0", // Crate checksum "cksum":"...", // Registry information (see Registry information) "registry":{"index-url":"sparse+https://registry-url/index/", "name": "my-registry"}, // Additional command-line args (optional) "args":[] }

获取成功响应

  • 发送者:凭据提供者
  • 目的:将凭据提供给 Cargo
{"Ok":{ // Response kind: this was a get request "kind":"get", // Token to send to the registry "token":"...", // Cache control. Can be one of the following: // * "never": do not cache // * "session": cache for the current cargo session // * "expires": cache for the current cargo session until expiration "cache":"expires", // Unix timestamp (only for "cache": "expires") "expiration":1693942857, // Is the token operation independent? "operation_independent":true }}

token 将作为 Authorization HTTP 标头的值发送到注册表。

operation_independent 指示令牌是否可以在不同的操作(例如发布或获取)之间缓存。通常,这应为 true,除非提供者想要生成特定操作范围的令牌。

登录成功响应

  • 发送者:凭据提供者
  • 目的:指示登录成功
{"Ok":{ // Response kind: this was a login request "kind":"login" }}

注销成功响应

  • 发送者:凭据提供者
  • 目的:指示注销成功
{"Ok":{ // Response kind: this was a logout request "kind":"logout" }}

失败响应(不支持 URL)

  • 发送者:凭据提供者
  • 目的:向 Cargo 提供错误信息
{"Err":{ "kind":"url-not-supported" }}

如果凭据提供者设计为仅处理特定的注册表 URL,并且给定的 URL 不受支持,则发送此消息。如果可用,Cargo 将尝试另一个提供者。

失败响应(未找到)

  • 发送者:凭据提供者
  • 目的:向 Cargo 提供错误信息
{"Err":{ // Error: The credential could not be found in the provider. "kind":"not-found" }}

如果找不到凭据则发送此消息。对于 get 请求(其中凭据不可用)或 logout 请求(其中未找到要删除的内容),这是预期的。

失败响应(不支持操作)

  • 发送者:凭据提供者
  • 目的:向 Cargo 提供错误信息
{"Err":{ // Error: The credential could not be found in the provider. "kind":"operation-not-supported" }}

如果凭据提供者不支持请求的操作,则发送此消息。如果提供者仅支持 get,并且请求 login,则提供者应使用此错误进行响应。

失败响应(其他)

  • 发送者:凭据提供者
  • 目的:向 Cargo 提供错误信息
{"Err":{ // Error: something else has failed "kind":"other", // Error message string to be displayed "message": "free form string error message", // Detailed cause chain for the error (optional) "caused-by": ["cause 1", "cause 2"] }}

请求读取令牌的通信示例

  1. Cargo 生成凭据进程,捕获标准输入和标准输出。
  2. 凭据进程将 Hello 消息发送到 Cargo
    { "v": [1] }
  3. Cargo 将 CredentialRequest 消息发送到凭据进程(为了便于阅读添加了换行符)。
    { "v": 1, "kind": "get", "operation": "read", "registry":{"index-url":"sparse+https://registry-url/index/"} }
  4. 凭据进程将 CredentialResponse 发送到 Cargo(为了便于阅读添加了换行符)。
    { "token": "...", "cache": "session", "operation_independent": true }
  5. Cargo 关闭到凭据提供者的标准输入管道,并且它退出。
  6. 在与此注册表交互时,Cargo 在会话的剩余时间内(直到 Cargo 退出)使用该令牌。