AK="ak_xxxxxxxx"
SK="sk_xxxxxxxx"
METHOD="POST"
URL_PATH="/v1/zones/12/records"
QUERY=""
BODY='{"host":"www","type":"A","value":"192.0.2.10"}'
TS=$(date +%s)
NONCE=$(openssl rand -hex 12)
BODY_HASH=$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | awk '{print $NF}')
SIGN=$(printf '%s\n%s\n%s\n%s\n%s\n%s' "$METHOD" "$URL_PATH" "$QUERY" "$TS" "$NONCE" "$BODY_HASH" \
| openssl dgst -sha256 -hmac "$SK" -binary | base64)
curl -X "$METHOD" "https://openapi-dev.okdns.ai$URL_PATH" \
-H "Content-Type: application/json" \
-H "X-Access-Key: $AK" -H "X-Timestamp: $TS" -H "X-Nonce: $NONCE" -H "X-Signature: $SIGN" \
-d "$BODY"import base64, hashlib, hmac, json, secrets, time
import requests # pip install requests
BASE = "https://openapi-dev.okdns.ai"
AK, SK = "ak_xxxxxxxx", "sk_xxxxxxxx"
def call(method, path, query="", body=None):
raw = json.dumps(body, separators=(",", ":")).encode() if body is not None else b""
ts, nonce = str(int(time.time())), secrets.token_hex(12)
to_sign = "\n".join([method, path, query, ts, nonce, hashlib.sha256(raw).hexdigest()])
sign = base64.b64encode(hmac.new(SK.encode(), to_sign.encode(), hashlib.sha256).digest()).decode()
headers = {"Content-Type": "application/json", "X-Access-Key": AK,
"X-Timestamp": ts, "X-Nonce": nonce, "X-Signature": sign}
url = BASE + path + ("?" + query if query else "")
r = requests.request(method, url, data=raw, headers=headers, timeout=30)
return r.json()
print(call("GET", "/v1/zones"))
print(call("POST", "/v1/zones/12/records", body={"host": "www", "type": "A", "value": "192.0.2.10"}))package main
import (
"bytes"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"net/http"
"strconv"
"time"
)
const (
base = "https://openapi-dev.okdns.ai"
ak = "ak_xxxxxxxx"
sk = "sk_xxxxxxxx"
)
func call(method, path, query string, body []byte) (string, error) {
ts := strconv.FormatInt(time.Now().Unix(), 10)
n := make([]byte, 12)
rand.Read(n)
nonce := hex.EncodeToString(n)
h := sha256.Sum256(body)
toSign := method + "\n" + path + "\n" + query + "\n" + ts + "\n" + nonce + "\n" + hex.EncodeToString(h[:])
m := hmac.New(sha256.New, []byte(sk))
m.Write([]byte(toSign))
url := base + path
if query != "" {
url += "?" + query
}
req, _ := http.NewRequest(method, url, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Access-Key", ak)
req.Header.Set("X-Timestamp", ts)
req.Header.Set("X-Nonce", nonce)
req.Header.Set("X-Signature", base64.StdEncoding.EncodeToString(m.Sum(nil)))
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
return string(out), nil
}
func main() {
fmt.Println(call("GET", "/v1/zones", "", nil))
fmt.Println(call("POST", "/v1/zones/12/records", "", []byte(`{"host":"www","type":"A","value":"192.0.2.10"}`)))
}import crypto from 'node:crypto'
const BASE = 'https://openapi-dev.okdns.ai'
const AK = 'ak_xxxxxxxx'
const SK = 'sk_xxxxxxxx'
async function call(method, path, query = '', body) {
const raw = body === undefined ? '' : JSON.stringify(body)
const ts = String(Math.floor(Date.now() / 1000))
const nonce = crypto.randomBytes(12).toString('hex')
const hash = crypto.createHash('sha256').update(raw).digest('hex')
const toSign = [method, path, query, ts, nonce, hash].join('\n')
const sign = crypto.createHmac('sha256', SK).update(toSign).digest('base64')
const res = await fetch(BASE + path + (query ? '?' + query : ''), {
method,
headers: { 'Content-Type': 'application/json', 'X-Access-Key': AK, 'X-Timestamp': ts, 'X-Nonce': nonce, 'X-Signature': sign },
body: raw || undefined,
})
return res.json()
}
console.log(await call('GET', '/v1/zones'))
console.log(await call('POST', '/v1/zones/12/records', '', { host: 'www', type: 'A', value: '192.0.2.10' }))