Xác minh webhook hiệu năng cao trong Rust với Axum. Thêm nhận diện khách truy cập, phát hiện bot và smart signals vào ứng dụng Rust của bạn trong vài phút.
Thêm SDK vào dự án của bạn với trình quản lý gói ưa thích.
npm install axumyarn add axumpnpm add axumBắt đầu vận hành với thiết lập tối thiểu.
use axum::{body::Bytes, http::HeaderMap, routing::post, Router};async fn webhook(headers: HeaderMap, body: Bytes) -> &'static str { // verify headers["x-tracio-signature"] against body, then act println!("{}", String::from_utf8_lossy(&body)); "OK"}#[tokio::main]async fn main() { let app = Router::new().route("/webhook/tracio", post(webhook)); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap();}Các mẫu hình sẵn sàng cho production với xử lý lỗi, trạng thái tải và cấu hình nâng cao.
use axum::{body::Bytes, http::{HeaderMap, StatusCode}, routing::post, Router};use hmac::{Hmac, Mac};use sha2::Sha256;use serde::Deserialize;type HmacSha256 = Hmac<Sha256>;#[derive(Deserialize)]struct Bot { result: String,}#[derive(Deserialize)]struct Event { #[serde(rename = "visitorId")] visitor_id: String, bot: Bot,}// Recompute the HMAC-SHA256 over "<t>.<rawBody>" and compare it.fn verify(body: &[u8], header: &str, secret: &[u8]) -> bool { let (mut t, mut v1) = ("", ""); for kv in header.split(',') { match kv.split_once('=') { Some(("t", val)) => t = val, Some(("v1", val)) => v1 = val, _ => {} } } let mut mac = HmacSha256::new_from_slice(secret).unwrap(); mac.update(t.as_bytes()); mac.update(b"."); mac.update(body); match hex::decode(v1) { Ok(sig) => mac.verify_slice(&sig).is_ok(), Err(_) => false, }}async fn webhook(headers: HeaderMap, body: Bytes) -> Result<&'static str, StatusCode> { let secret = std::env::var("TRACIO_WEBHOOK_SECRET").unwrap_or_default(); let sig = headers .get("x-tracio-signature") .and_then(|v| v.to_str().ok()) .unwrap_or(""); if !verify(&body, sig, secret.as_bytes()) { return Err(StatusCode::UNAUTHORIZED); } let event: Event = serde_json::from_slice(&body).map_err(|_| StatusCode::BAD_REQUEST)?; if event.bot.result == "bot" { println!("flagging bot visitor {}", event.visitor_id); } Ok("OK")}#[tokio::main]async fn main() { let app = Router::new().route("/webhook/tracio", post(webhook)); let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); axum::serve(listener, app).await.unwrap();}Tất cả tùy chọn có sẵn để khởi tạo và cấu hình SDK.
publicKeystringPublic key của bạn từ bảng điều khiển — an toàn để đưa lên trình duyệtendpointstringURL endpoint tùy chỉnh cho các triển khai định tuyến qua proxy — URL chỉ định rõ sẽ thắng regionregionstringVùng dữ liệu: us hoặc eutimeoutMsnumberThời gian chờ cho toàn bộ lệnh gọi getResult(), tính bằng mili giâylinkedIdstringID tài khoản nội bộ của bạn cho người dùng đã đăng nhập, để các lượt truy cập chung thiết bị có thể được liên kếttagstringNhãn tự do gắn vào yêu cầu nhận diện, ví dụ checkout hoặc logindebugbooleanGhi vòng đời script và hoạt động mạng ra console của trình duyệtscriptUrlstringGhi đè toàn bộ URL script agent — cho self-hosting hoặc Subresource IntegrityTìm hiểu sâu hơn với tài liệu API đầy đủ, cấu hình webhook và các hướng dẫn nâng cao.
Tài liệu API đầy đủ, hướng dẫn tích hợp và các thực hành tốt nhất.
Gửi sự kiện thời gian thực, schema payload và xác minh chữ ký.
Cấu hình thông báo sự kiện thời gian thực cho mỗi lần nhận diện thiết bị.
Thêm fingerprinting thiết bị vào ứng dụng Rust của bạn trong chưa đầy 5 phút.