Files
sign-doc/rust/README.md

5.5 KiB
Raw Permalink Blame History

API签名工具 - Rust实现

项目结构

根据实际项目文件结构:

rust/
├── Cargo.toml               # Cargo配置文件
├── Cargo.lock               # 依赖锁定文件
├── src/
│   ├── main.rs              # 命令行工具入口
│   └── lib.rs               # 库入口和核心实现
└── target/                  # 构建输出目录

使用方法

构建项目

cargo build --release

运行命令行工具

cargo run --release -- [选项]

或使用编译后的二进制文件:

./target/release/apisign [选项]

命令行选项

选项 描述
-a, --algorithm 签名算法: md5, sha1, sha256, hmac-sha256
-u, --url API基础URL
-p, --param 请求参数格式为key=value可多次使用
-k, --key 访问密钥ID
-s, --secret 密钥
-c, --channel 合作渠道方ID
-h, --help 显示帮助信息
-m, --mode 操作模式: sign_url, sign_params, verify
-t, --timestamp 自定义时间戳
-n, --nonce 自定义随机字符串
--version 显示版本信息

常用命令示例

基本用法

./target/release/apisign

自定义参数

./target/release/apisign \
  -u "https://api.example.com/user/info" \
  -p "userId=12345" -p "action=getInfo" \
  -k "YOUR_ACCESS_KEY" \
  -s "YOUR_SECRET_KEY" \
  -c "3"

指定签名算法

./target/release/apisign -a sha256

生成签名参数

./target/release/apisign -m sign_params -p "userId=12345" -p "action=getData"

验证签名

./target/release/apisign -m verify -p "userId=12345" -p "action=getData" -p "AccessKeyId=test-key" -p "channelId=test-channel" -p "timestamp=1621234567890" -p "nonce=abc123" -p "sign=calculated-signature-here"

帮助信息

./target/release/apisign --help

API接口测试实例

使用真实API接口进行测试

# 未签名的API调用测试 - 返回错误
curl "https://api-v1.sound-force.com:8443/p/album/single/media-url?channelId=3&singleId=381980"
# 返回: {"code":400,"data":null,"msg":"Missing AccessKeyId","success":false}

# 生成访问https://api-v1.sound-force.com:8443/p/album/single/media-url的签名URL
./target/release/apisign \
  -a md5 \
  -u "https://api-v1.sound-force.com:8443/p/album/single/media-url" \
  -p "singleId=381980" \
  -k "YOUR_ACCESS_KEY" \
  -s "YOUR_SECRET_KEY" \
  -c "3"

# 使用curl测试API接口
signed_url=$(./target/release/apisign \
  -a md5 \
  -u "https://api-v1.sound-force.com:8443/p/album/single/media-url" \
  -p "singleId=381980" \
  -k "YOUR_ACCESS_KEY" \
  -s "YOUR_SECRET_KEY" \
  -c "3" | grep -A 1 "签名后的URL:" | tail -n 1)
curl -v "$signed_url"

请注意:

  • 替换YOUR_ACCESS_KEY为实际的访问密钥ID
  • 替换YOUR_SECRET_KEY为实际的密钥
  • 示例使用的渠道ID为3,请根据实际情况调整

使用有效的密钥和签名后API接口将返回成功响应(状态码200)并提供媒体URL数据。

Rust Reqwest客户端测试示例

use std::process::Command;
use reqwest;
use std::io::{self, Write};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 获取签名URL
    let output = Command::new("./target/release/apisign")
        .args(&[
            "-a", "md5", 
            "-u", "https://api-v1.sound-force.com:8443/p/album/single/media-url",
            "-p", "singleId=381980",
            "-k", "YOUR_ACCESS_KEY",
            "-s", "YOUR_SECRET_KEY",
            "-c", "3"
        ])
        .output()?;
    
    let output_str = String::from_utf8(output.stdout)?;
    let lines: Vec<&str> = output_str.lines().collect();
    
    // 提取URL
    let mut signed_url = "";
    for (i, line) in lines.iter().enumerate() {
        if line.contains("签名后的URL:") && i + 1 < lines.len() {
            signed_url = lines[i + 1].trim();
            break;
        }
    }
    
    println!("签名生成的URL: {}", signed_url);
    
    if !signed_url.is_empty() {
        // 发送请求
        let client = reqwest::Client::new();
        let response = client.get(signed_url).send().await?;
        
        println!("状态码: {}", response.status());
        let body = response.text().await?;
        println!("响应内容: {}", body);
    } else {
        println!("无法从输出中获取签名URL");
    }
    
    Ok(())
}

代码集成

use apisign::{ApiSigner, SignOptions, SignatureAlgorithm};
use std::collections::HashMap;

fn main() {
    // 创建签名选项
    let options = SignOptions::new()
        .with_algorithm(SignatureAlgorithm::Md5);
    
    // 创建签名工具
    let signer = ApiSigner::new(options);
    
    // 准备请求参数
    let mut params = HashMap::new();
    params.insert("singleId".to_string(), "381980".to_string());
    
    // 执行签名
    let signed_params = signer.sign_request(
        &params, 
        "YOUR_ACCESS_KEY", 
        "YOUR_SECRET_KEY", 
        "3"
    ).unwrap();
    
    // 或签名URL
    let signed_url = signer.sign_url(
        "https://api-v1.sound-force.com:8443/p/album/single/media-url",
        &params,
        "YOUR_ACCESS_KEY", 
        "YOUR_SECRET_KEY",
        "3"
    ).unwrap();
    
    println!("{}", signed_url);
}

环境变量

该工具支持从.env文件加载以下配置:

  • ACCESS_KEY_ID: 访问密钥ID
  • SECRET_KEY: 密钥
  • CHANNEL_ID: 渠道ID
  • SIGN_ALGORITHM: 签名算法
  • API_BASE_URL: API基础URL