İmzalı istekler
İsteklerini HMAC imzasıyla koru.
Tek başına bir API anahtarı, her istekle birlikte yolculuk eden bir paroladır. Sızarsa, örneğin bir günlük dosyası veya yanlış yapılandırılmış bir eklenti yoluyla, elinde olan herkes programın için dönüşüm bildirebilir. Bu sayfada her isteği sunucundan asla çıkmayan ayrı bir İmza anahtarı ile nasıl imzalayacağını ve cli.gs'nin imzasız her şeyi nasıl reddedeceğini öğrenirsin.
Kısaca:
- İmza anahtarı ilk API anahtarınla birlikte gelir ve yalnızca bir kez gösterilir.
- Her istek üç başlık taşır: bir zaman damgası, tek kullanımlık bir nonce ve bir HMAC-SHA256 imzası.
- Tam olarak gönderdiğin baytları imzala. İmza hatalarının çoğu gövdenin yeniden kodlanmasından kaynaklanır.
- Önce imzalı isteklerle test et, sonra İmzasız istekleri reddet kutusunu işaretle.
İmza anahtarı nereden gelir
İmza anahtarı ilk API anahtarınla birlikte gösterilir. Onu entegrasyon sayfasında API anahtarı altında, İmza anahtarı etiketiyle bulursun. API anahtarı gibi yalnızca bir kez gösterilir. Mağazanın gizli anahtar yapılandırmasında API anahtarının yanında sakla.

Daha sonra yeni bir anahtar üretmek aynı imza anahtarını korur. Anahtar değiştirirken istekler geçerli kalır.
Üç başlık
İmzalı bir istek üç ek başlık taşır:
| Başlık | Değer |
|---|---|
X-Cligs-Timestamp | Unix saniye cinsinden geçerli zaman, ör. 1790000000 |
X-Cligs-Nonce | Rastgele, tek kullanımlık bir değer, 8 ile 128 karakter arası (harfler, rakamlar ve . _ ~ : + / = -) |
X-Cligs-Signature | Küçük harfli hex olarak HMAC-SHA256 imzası |
Nonce, yalnızca bir kez kullandığın bir değerdir. Yakalanan bir isteğin yeniden oynatılmasını engeller.
Ne imzalanır
İmza, yeni satır (\n) ile birleştirilen beş satır üzerinden hesaplanır:
POST
/api/v1/track/conversion
1790000000
3f9c2b7e41d04a8b9e6f0c1d2a3b4c5d
<hex SHA-256 of the exact request body>Beş satır şunlardır: büyük harfle HTTP yöntemi, ana bilgisayar ve sorgu dizesi olmadan yol, zaman damgası, nonce ve gövdenin hex olarak SHA-256 özeti. HMAC anahtarı, tam gösterildiği haliyle düz bir dize olarak kullanılan imza anahtarıdır.
Bir isteği ne zaman kabul ederiz
- Zaman damgası saatimizden en fazla beş dakika sapıyorsa. Sunucu saatini NTP ile eşitlenmiş tut.
- Nonce daha önce programın tarafından kullanılmadıysa.
- İmza, aldığımız gövdeyle bayt bayt eşleşiyorsa.
Node.js yardımcısı
import crypto from "node:crypto";
const BASE_URL = "https://cli.gs";
const API_KEY = process.env.CLIGS_API_KEY;
const SIGNING_SECRET = process.env.CLIGS_SIGNING_SECRET;
// Returns the three X-Cligs-* headers for one request.
export function cligsSignatureHeaders(method, path, body, secret = SIGNING_SECRET) {
const timestamp = String(Math.floor(Date.now() / 1000));
const nonce = crypto.randomBytes(16).toString("hex");
const bodyHash = crypto.createHash("sha256").update(body, "utf8").digest("hex");
const canonical = [method.toUpperCase(), path, timestamp, nonce, bodyHash].join("\n");
const signature = crypto.createHmac("sha256", secret).update(canonical, "utf8").digest("hex");
return {
"X-Cligs-Timestamp": timestamp,
"X-Cligs-Nonce": nonce,
"X-Cligs-Signature": signature,
};
}
// Sends a signed POST to the cli.gs API.
export async function cligsPost(path, payload) {
const body = JSON.stringify(payload); // sign exactly the bytes you send
const res = await fetch(BASE_URL + path, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
...cligsSignatureHeaders("POST", path, body),
},
body,
signal: AbortSignal.timeout(5000),
});
return { status: res.status, data: await res.json().catch(() => null) };
}
// Usage:
// await cligsPost("/api/v1/track/conversion", { ref, orderId: "100234", amount: "149.99", currency: "EUR" });
// await cligsPost("/api/v1/track/reversal", { orderId: "100234", reason: "RETURN" });PHP yardımcısı
<?php
// Returns the three X-Cligs-* headers for one request, ready for CURLOPT_HTTPHEADER.
function cligs_signature_headers(string $method, string $path, string $body, string $secret): array {
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(16));
$canonical = implode("\n", [strtoupper($method), $path, $timestamp, $nonce, hash('sha256', $body)]);
$signature = hash_hmac('sha256', $canonical, $secret);
return [
'X-Cligs-Timestamp: ' . $timestamp,
'X-Cligs-Nonce: ' . $nonce,
'X-Cligs-Signature: ' . $signature,
];
}
// Sends a signed POST to the cli.gs API.
function cligs_post(string $path, array $payload): array {
$body = json_encode($payload); // sign exactly the bytes you send
$ch = curl_init('https://cli.gs' . $path);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => array_merge([
'Authorization: Bearer ' . getenv('CLIGS_API_KEY'),
'Content-Type: application/json',
], cligs_signature_headers('POST', $path, $body, getenv('CLIGS_SIGNING_SECRET'))),
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
return ['status' => $status, 'body' => json_decode((string) $response, true)];
}WordPress'te aynı başlıkları wp_remote_post() fonksiyonuna ilişkisel dizi olarak geçir. wp_json_encode() fonksiyonunu bir kez çağır ve sonucu hem gövde hem imza için kullan.
"İmzasız istekleri reddet" seçeneğini aç
Sen açana kadar imzalama isteğe bağlıdır. İmzası olan bir istek kontrol edilir. İmzasız bir istek yalnızca API anahtarıyla kabul edilir. Mağazan her isteği imzalamaya başladığında:
- Birkaç imzalı test dönüşümü gönder ve kabul edildiklerini kontrol et.
- İmzalı istekler altında İmzasız istekleri reddet kutusunu işaretle.
- Kaydet düğmesine tıkla.
Bundan sonra geçerli imzası olmayan her dönüşüm ve iptal isteği reddedilir.
Bir imza reddedildiğinde
İmza sorunu, HTTP 401 ve error içinde kısa bir nedenle yanıtlanır:
error | Neden |
|---|---|
signature required | İmzasız istekleri reddet açık ve isteğin imzası yoktu |
stale or missing timestamp | Zaman damgası eksik, saniye cinsinden değil veya beş dakikadan fazla sapıyor |
invalid nonce | Nonce eksik, çok kısa, çok uzun veya başka karakterler içeriyor |
nonce already used | Aynı nonce iki kez gönderildi. Yeniden denemeler dahil her istek için yeni bir tane üret |
invalid signature | İmza eşleşmiyor |
no signing secret issued for this programme | İmza gönderdin ama programın imza anahtarı yok |
invalid signature hatalarının çoğu, gönderilenden farklı bir şeyi imzalamaktan kaynaklanır. Tipik nedenler: JSON'u imzaladıktan sonra yeniden kodlamak, yol yerine tam URL'yi imzalamak veya gövdeye boşluk ekleyen bir çerçeve. Gövde dizesini bir kez oluştur ve her ikisi için de onu kullan.
Sonraki adımlar
İstekler imzalandığına göre iadeleri ve iptalleri kur.