凭据提供程序协议
本文档描述了构建 Cargo 凭据提供程序的信息。有关设置或使用凭据提供程序的信息,请参阅注册表身份验证。
使用外部凭据提供程序时,Cargo 使用作为单行 JSON 传递的 stdin/stdout 消息与凭据提供程序进行通信。
Cargo 将始终使用 --cargo-plugin
参数执行凭据提供程序。这使得凭据提供程序可执行文件可以具有 Cargo 所需功能之外的其他功能。其他参数通过 args
字段包含在 JSON 中。
JSON 消息
为了便于阅读,本文档中的 JSON 消息添加了换行符。实际消息不得包含换行符。
凭据问候
- 发送者:凭据提供程序
- 目的:用于在进程启动时识别支持的协议
{
"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 -- <additional args>
传递额外的命令行参数。这些附加参数将包含在 Cargo 配置中任何参数之后的 args
字段中。
读取请求
- 发送者:Cargo
- 目的:获取用于读取包信息的凭据
{
// 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
- 目的:获取用于发布包的凭据
{
// 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"]
}}
请求读取令牌的示例通信
- Cargo 生成凭据进程,捕获 stdin 和 stdout。
- 凭据进程向 Cargo 发送 Hello 消息
{ "v": [1] }
- Cargo 向凭据进程发送 CredentialRequest 消息(为了便于阅读,添加了换行符)。
{ "v": 1, "kind": "get", "operation": "read", "registry":{"index-url":"sparse+https://registry-url/index/"} }
- 凭据进程向 Cargo 发送 CredentialResponse(为了便于阅读,添加了换行符)。
{ "token": "...", "cache": "session", "operation_independent": true }
- Cargo 关闭到凭据提供程序的 stdin 管道,然后退出。
- Cargo 在与该注册表交互时,会在剩余的会话时间(直到 Cargo 退出)使用该令牌。