Apache Reqsign 0.20.7 常用工具与 API 详解

Apache Reqsign 0.20.7 常用工具与 API 详解:Reqsign 以 Rust crate 形态提供、配套 cargo 命令(search/info/add/vendor/tree),逐类速查 Signer/Context/Credential 提供者/RequestSigner/Credential 核心 API 与各云服务便捷入口,含代码示例与 FAQ,全程实测。

Apache ReqsignApache Reqsign2026/10/13

Apache Reqsign 0.20.7 常用工具与 API 详解

目标:详解 Apache Reqsign 0.20.7 的核心 API 与配套工具使用。Reqsign 以 Rust crate(库)形态提供,没有独立的命令行签名程序,日常操作通过 cargo 工具管理依赖、通过 Rust API 完成签名。本文按类速查 Signer/Context/Credential 提供者/RequestSigner/Credential 等关键 API 与各云服务便捷入口,给出代码示例与 FAQ。所有示例在 Ubuntu 22.04.5 + rustc 1.99.0 环境实测。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • Rust 工具链:rustc 1.99.0 / cargo 1.99.0(rustup stable)
  • Reqsign 版本:0.20.7(feature:aws-v4;依赖 reqsign-aws-v4 3.3.1 / reqsign-aws-core 3.2.0 / reqsign-core 3.3.2)
  • 示例工程:/root/reqsign-demo/

二、工具概览

Reqsign 以「Rust crate + cargo 工具」形态提供,没有 reqsign 命令行可执行程序;对请求的全部签名操作都通过 Rust API 完成。配套工具是 cargo 本身:

工具/API 类别代表命令/类作用
依赖管理cargo search reqsign / cargo info reqsign查版本、license、rust-version、features
依赖引入cargo add reqsign --features aws-v4写入 Cargo.toml 依赖
依赖查看cargo tree展示传递依赖树
离线打包cargo vendor打包全部依赖源码供内网编译
构建运行cargo build / cargo run编译与运行示例
签名组装Signer / Context签名入口与基础设施
凭据获取StaticCredentialProvider / EnvCredentialProvider / DefaultCredentialProvider提供访问凭据
服务签名器RequestSigner / aliyun::RequestSigner / tencent::RequestSigner按云服务规范生成签名

三、前置条件

安装 Rust 工具链与 reqsign 依赖,编译运行示例工程:

source "$HOME/.cargo/env"
cd /root/reqsign-demo
cargo build

四、核心 API 详解

4.1 Signer(签名入口)

Signer::new(ctx, credential_provider, request_signer) 组装三要素后,用 sign() 对请求签名:

use reqsign::{Context, Signer};
use reqsign::aws::{RequestSigner, StaticCredentialProvider};

let ctx = Context::new();
let cred = StaticCredentialProvider::new("AKIDEXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
let signer = Signer::new(ctx, cred, RequestSigner::new("s3", "us-east-1"));

let mut parts = http::Request::get("http://127.0.0.1:8000/my-bucket/demo.txt")
    .body(())
    .unwrap()
    .into_parts()
    .0;
signer.sign(&mut parts, None).await?;   // 成功后 parts.uri / parts.headers 被改写

常用方法:

方法说明
Signer::new(ctx, provider, signer)组装签名器
with_context(ctx) / with_credential_provider(p) / with_request_signer(s)链式替换组件
sign(&mut Parts, Option<Duration>)异步执行签名,成功只改 uri 与 headers

4.2 Context(上下文基础设施)

Context 提供签名所需的文件读取、HTTP 发送、环境变量与命令执行能力:

use reqsign::default_context;
use reqsign::Context;

let ctx = default_context();   // TokioFileRead + ReqwestHttpSend + OsEnv + TokioCommandExecute
// 自定义:
let ctx = Context::new()
    .with_env(reqsign::OsEnv);
方法说明
default_context()默认实现组合(需 default-context feature)
Context::new()空上下文,逐项注入
with_file_read(impl FileRead) / with_http_send(impl HttpSend) / with_env(impl Env) / with_command_execute(impl CommandExecute)替换对应组件

4.3 凭据提供者(Credential Provider)

三种常用提供者:

use reqsign::aws::{StaticCredentialProvider, EnvCredentialProvider, DefaultCredentialProvider};

// 静态凭据(演示/固定凭据)
let p1 = StaticCredentialProvider::new("AKIDEXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");

// 环境变量凭据(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN)
let p2 = EnvCredentialProvider::new();

// 默认凭据链(env → profile → sso → web_identity → process → ecs → imds,生产推荐)
let p3 = DefaultCredentialProvider::new();
提供者说明
StaticCredentialProvider::new(ak, sk)固定凭据
EnvCredentialProvider::new()环境变量凭据
DefaultCredentialProvider::new()默认凭据链,自动从环境变量、~/.aws/credentials、SSO、Web Identity、ECS/IMDS 取凭据
DefaultCredentialProvider::new().push_front(p)把自定义提供者插到链首优先尝试

4.4 RequestSigner(服务签名器)

RequestSigner 按云服务规范计算签名(AWS SigV4),构造参数为服务名与区域:

use reqsign::aws::RequestSigner;

let signer = RequestSigner::new("s3", "us-east-1");        // S3 / 区域 us-east-1
let s3express = RequestSigner::new("s3express", "us-west-2")
    .with_standard_session_token();                        // S3 Express + IAM/STS 临时凭据
方法说明
new(service, region)指定签名服务与区域
with_standard_session_token()会话令牌用标准 x-amz-security-token 表示(S3 Express + IAM/STS)

4.5 Credential(凭据数据)

签名使用的凭据数据,由各提供者产出:

// Credential { access_key_id, secret_access_key, session_token: Option<String>, expires_in: Option<Timestamp> }

四个字段:access_key_id、secret_access_key(仅参与计算,Debug 输出会被脱敏)、session_token(临时会话令牌,可选)、expires_in(过期时间,可选)。签名器内部会缓存凭据并在过期前自动刷新。

4.6 各云服务便捷入口(default_signer)

开启对应 feature 后,各云服务提供一步到位的 default_signer 便捷函数(默认上下文 + 默认凭据链 + 服务签名器):

// AWS S3(feature aws-v4):服务 s3、区域 us-east-1
let signer = reqsign::aws::default_signer("s3", "us-east-1");

// 阿里云 OSS(feature aliyun):按 bucket 签名
// let signer = reqsign::aliyun::default_signer("mybucket");

// 腾讯云 COS(feature tencent)
// let signer = reqsign::tencent::default_signer();

💡 说明:aws::default_signer 实测可用(依赖 default-context feature);aliyun::default_signer(bucket)、tencent::default_signer() 为源码级 API(feature 未开启时不可用),用法一致:signer.sign(&mut parts, None).await?。

4.7 配套 cargo 工具命令

依赖生命周期管理(全部实测回显):

cargo search reqsign --limit 3     # 查 crates.io:reqsign = "0.20.7"(当前最新版)
cargo info reqsign                # version 0.20.7 / license Apache-2.0 / rust-version 1.86.0 / features
cargo add reqsign --features aws-v4   # Adding reqsign v0.20.7 to dependencies
cargo tree                        # 查看传递依赖树(reqsign v0.20.7 → reqsign-aws-v4 v3.3.1 → reqsign-core v3.3.2)
cargo vendor --locked vendor      # 打包离线依赖(输出 replace-with 配置提示)
cargo remove reqsign              # Removing reqsign from dependencies(卸载)

五、完整最小可运行示例

把上述 API 串成一次「签名 + 打印签名头 + 发送验证」的完整程序(对应《构建并运行示例应用指南》篇的可执行源码),核心调用如下:

use reqsign::aws::{RequestSigner, StaticCredentialProvider, EMPTY_STRING_SHA256};
use reqsign::{Context, Signer};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let cred = StaticCredentialProvider::new("AKIDEXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
    let ctx = Context::new();
    let signer = Signer::new(ctx, cred, RequestSigner::new("s3", "us-east-1"));

    let req = http::Request::get("http://127.0.0.1:8000/my-bucket/demo.txt")
        .header("x-amz-content-sha256", EMPTY_STRING_SHA256)
        .body(())
        .unwrap();
    let (mut parts, _) = req.into_parts();
    signer.sign(&mut parts, None).await?;

    println!("authorization: {}", parts.headers.get("authorization").unwrap().to_str()?);
    println!("x-amz-date: {}", parts.headers.get("x-amz-date").unwrap().to_str()?);
    Ok(())
}

运行实测输出(节选):

== 签名后的请求头 ==
authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20261012/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=37962216ce11dc6ee635a8aac517e295cb23b0e6856a687141d085e31901c711
x-amz-date: 20261012T164829Z
x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

六、注意事项

⚠️ 注意:

  1. Reqsign 没有 reqsign 命令行工具,必须通过 Rust 代码调用 crate 完成签名;cargo 只是依赖管理/构建工具。
  2. signer.sign() 操作 http::request::Parts:构造请求用 http::Request::builder(),得到 Parts 后签名,再把签名头交给自己的 HTTP 客户端发送(reqwest/curl 均可)。
  3. 各云服务模块受 feature 开关控制(aws-v4、aliyun、tencent 等),未开启的模块在代码中引用会编译失败。
  4. 演示密钥 AKIDEXAMPLE 仅用于演示;生产凭据务必通过环境变量/配置文件/临时凭据链获取,切勿硬编码。

七、常见问题

Q1:Reqsign 有命令行工具吗? 没有独立的命令行签名程序。签名通过 Rust API 完成;依赖与构建用 cargo 工具(cargo add / cargo build / cargo run)。

Q2:引用 reqsign::aliyun 报错找不到模块? 未开启对应 feature。在 Cargo.toml 中把 aliyun(或 tencent 等)加入 features:reqsign = { version = "0.20.7", features = ["aws-v4", "aliyun"] }。

Q3:sign 返回错误(凭据为空/来源不可用)? 先确认凭据提供者能产出凭据:静态凭据两个参数非空;环境变量两个必填变量已导出;默认链在可联网且配置就绪的机器上使用。

Q4:如何把签名后的请求发给服务端? parts 中已有签名头(authorization / x-amz-date / 等),用 reqwest::Client 重建请求:client.request(method, uri).headers(headers).body(body).send();reqwest 0.12 的 Request 没有 from_parts 构造函数,须用上述 RequestBuilder 方式。

Q5:cargo vendor 后离线编译报缺依赖? vendor/ 生成后需按输出提示在工程 .cargo/config.toml 写入 [source.crates-io] replace-with = "vendored-sources"(详见《安装指南》篇第五节),再用 cargo build --offline 编译。

八、参考链接

  • Reqsign 官方文档:https://docs.rs/reqsign
  • crates.io:https://crates.io/crates/reqsign
  • Cargo 手册:https://doc.rust-lang.org/cargo/
  • AWS SigV4 签名规范:https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
  • 源码仓库:https://github.com/apache/opendal-reqsign