Rust / Tauri 接入指南

使用 reqwest 与 ed25519-dalek 在 Rust 或 Tauri 应用中完成授权闭环。

本指南覆盖完整闭环:激活 → 本地保存 → 启动校验 → 停用。示例假设你已经拿到工作区与一份授权码。

依赖:reqwest(blocking 或 async)、serde_json、ed25519-dalek、base64、hex-literal。

1. 激活

src/license.rs
use serde_json::json;

const BASE: &str = "https://keygate.unionuser.com";

pub fn activate(license_key: &str, device_id: &str) -> Result<String, Box<dyn std::error::Error>> {
    let client = reqwest::blocking::Client::new();
    let res = client
        .post(format!("{}/api/v1/license/activate", BASE))
        .json(&json!({
            "license_key": license_key,
            "identifier": device_id,
            "identifier_type": "device"
        }))
        .send()?;

    let body: serde_json::Value = res.json()?;
    if body["success"] != true {
        return Err(body["error"]["code"].as_str().unwrap_or("UNKNOWN").into());
    }
    Ok(body["data"]["token"].as_str().unwrap_or_default().to_string())
}

2. 离线验签

src/verify.rs
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use ed25519_dalek::{Signature, VerifyingKey};
use serde_json::Value;

const RAW_PUBLIC: [u8; 32] = hex_literal::hex!("bf17435ee7b937b3592808941683c21d37c4e124d95d4e8fdd86fe775dd23b11");

pub fn verify_token(token: &str, device_id: &str) -> Result<Value, Box<dyn std::error::Error>> {
    let (payload_b64, sig_b64) = token.split_once('.').ok_or("BAD_TOKEN")?;
    let sig_bytes = URL_SAFE_NO_PAD.decode(sig_b64)?;
    let signature = Signature::from_slice(&sig_bytes)?;
    let key = VerifyingKey::from_bytes(&RAW_PUBLIC)?;
    key.verify_strict(payload_b64.as_bytes(), &signature)?;

    let claims: Value = serde_json::from_slice(&URL_SAFE_NO_PAD.decode(payload_b64)?)?;
    if claims["did"] != device_id {
        return Err("DEVICE_MISMATCH".into());
    }
    Ok(claims)
}

3. 停用

src/license.rs
pub fn deactivate(license_key: &str, device_id: &str) -> Result<(), Box<dyn std::error::Error>> {
    reqwest::blocking::Client::new()
        .post(format!("{}/api/v1/license/deactivate", BASE))
        .json(&json!({ "license_key": license_key, "identifier": device_id }))
        .send()?;
    Ok(())
}

Tauri 提示

  • 把授权逻辑放在 Rust 侧(命令),前端只拿功能开关结果。
  • token 存到 app_data_dir,不要放进前端 localStorage。
  • ed25519-dalek 的 verify_strict 可拒绝弱公钥,建议使用。