Cloud WAF/Docs 中文 EN
Cloud WAF 是企业级 Web 防护管理平台。后端 Go + Gin REST API,前端 Vue 3 SPA,附带 zcloud CLI 工具用于自动化运维。

本文档属于 Cloud WAF — 企业 Web 防护管理平台
CLI 工具:zcloud · 5 大模块:guard / sys / analytics / cli_release / auth
完整 API 索引:/api/openapi.json · 文档地图:/sitemap.xml · AI 速读:/llms.txt


示例代码

总览

本页给出 5 个高频场景的完整调用示例,每个场景都用 curl / Python / Go 三种语言实现,可直接复制运行。所有示例假设:

api_url   = https://waf.example.com
username  = admin
password  = YOUR_PASSWORD

替换为你自己的 api_url 和凭据后即可使用。


场景 1:查 CLI 版本(公开接口)

无需鉴权,最简单的存活检查 / 联通性测试。

curl

curl -sS https://waf.example.com/api/cli/version

Python

import requests

resp = requests.get("https://waf.example.com/api/cli/version", timeout=5)
resp.raise_for_status()
print(resp.json()["data"]["version"])

Go

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "time"
)

func main() {
    client := &http.Client{Timeout: 5 * time.Second}
    resp, err := client.Get("https://waf.example.com/api/cli/version")
    if err != nil { panic(err) }
    defer resp.Body.Close()

    var out struct {
        Data struct{ Version string `json:"version"` } `json:"data"`
    }
    json.NewDecoder(resp.Body).Decode(&out)
    fmt.Println(out.Data.Version)
}

场景 2:登录拿 token

curl

TOKEN=$(curl -sS -X POST https://waf.example.com/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"YOUR_PASSWORD"}' \
  | jq -r '.data.token')

echo "token=$TOKEN"

Python

import requests

resp = requests.post(
    "https://waf.example.com/api/auth/login",
    json={"username": "admin", "password": "YOUR_PASSWORD"},
    timeout=5,
)
resp.raise_for_status()
token = resp.json()["data"]["token"]
print("token =", token)

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    body, _ := json.Marshal(map[string]string{
        "username": "admin",
        "password": "YOUR_PASSWORD",
    })
    resp, err := http.Post(
        "https://waf.example.com/api/auth/login",
        "application/json",
        bytes.NewReader(body),
    )
    if err != nil { panic(err) }
    defer resp.Body.Close()

    var out struct {
        Code int `json:"code"`
        Data struct{ Token string `json:"token"` } `json:"data"`
    }
    json.NewDecoder(resp.Body).Decode(&out)
    fmt.Println("token =", out.Data.Token)
}

场景 3:列出域名(鉴权)

curl

curl -sS https://waf.example.com/api/guard/domains \
  -H "Authorization: Bearer $TOKEN" \
  | jq '.data.list[] | {id, name, origin, status}'

Python

import requests

headers = {"Authorization": f"Bearer {token}"}
resp = requests.get(
    "https://waf.example.com/api/guard/domains",
    headers=headers,
    timeout=5,
)
resp.raise_for_status()
for d in resp.json()["data"]["list"]:
    print(f"{d['id']:>4}  {d['name']:<40}  {d['origin']}")

Go

req, _ := http.NewRequest("GET", "https://waf.example.com/api/guard/domains", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()

var out struct {
    Data struct {
        List []struct {
            ID     int    `json:"id"`
            Name   string `json:"name"`
            Origin string `json:"origin"`
        } `json:"list"`
    } `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&out)
for _, d := range out.Data.List {
    fmt.Printf("%4d  %-40s  %s\n", d.ID, d.Name, d.Origin)
}

场景 4:分页查用户列表(鉴权 + 分页)

curl

curl -sS "https://waf.example.com/api/sys/users?page=1&size=20&keyword=ops" \
  -H "Authorization: Bearer $TOKEN" \
  | jq '.data | {total, page, size, count: (.list | length)}'

Python

import requests

resp = requests.get(
    "https://waf.example.com/api/sys/users",
    params={"page": 1, "size": 20, "keyword": "ops"},
    headers={"Authorization": f"Bearer {token}"},
    timeout=5,
)
resp.raise_for_status()
data = resp.json()["data"]
print(f"total={data['total']} page={data['page']} size={data['size']}")
for u in data["list"]:
    print(f"  - {u['username']} ({u['display_name']})")

Go

req, _ := http.NewRequest(
    "GET",
    "https://waf.example.com/api/sys/users?page=1&size=20&keyword=ops",
    nil,
)
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()

var out struct {
    Data struct {
        Total int `json:"total"`
        Page  int `json:"page"`
        Size  int `json:"size"`
        List  []struct {
            Username    string `json:"username"`
            DisplayName string `json:"display_name"`
        } `json:"list"`
    } `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&out)
fmt.Printf("total=%d page=%d size=%d\n", out.Data.Total, out.Data.Page, out.Data.Size)
for _, u := range out.Data.List {
    fmt.Printf("  - %s (%s)\n", u.Username, u.DisplayName)
}

场景 5:401 自动重试 Wrapper(生产推荐)

把"登录 + 401 自动重登 + 重试"封装到客户端,业务层只管调用 API。

Python(完整可运行)

import requests

class CloudWAF:
    def __init__(self, base_url: str, username: str, password: str, timeout: float = 10):
        self.base = base_url.rstrip("/")
        self.username = username
        self.password = password
        self.timeout = timeout
        self.session = requests.Session()
        self.token = None
        self._login()

    def _login(self):
        r = self.session.post(
            f"{self.base}/api/auth/login",
            json={"username": self.username, "password": self.password},
            timeout=self.timeout,
        )
        r.raise_for_status()
        self.token = r.json()["data"]["token"]

    def call(self, method: str, path: str, **kwargs):
        headers = kwargs.pop("headers", {})
        headers["Authorization"] = f"Bearer {self.token}"
        url = f"{self.base}{path}"
        r = self.session.request(method, url, headers=headers, timeout=self.timeout, **kwargs)
        if r.status_code == 401:
            self._login()
            headers["Authorization"] = f"Bearer {self.token}"
            r = self.session.request(method, url, headers=headers, timeout=self.timeout, **kwargs)
        r.raise_for_status()
        return r.json()

# 使用示例
client = CloudWAF("https://waf.example.com", "admin", "YOUR_PASSWORD")
domains = client.call("GET", "/api/guard/domains")["data"]["list"]
print(f"got {len(domains)} domains")

# 创建一个域名
new_domain = client.call("POST", "/api/guard/domains", json={
    "name": "test.example.com",
    "origin": "10.0.0.99",
})
print("created id =", new_domain["data"]["id"])

Go(完整可运行)

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "time"
)

type Client struct {
    BaseURL  string
    Username string
    Password string
    Token    string
    HTTP     *http.Client
}

func New(baseURL, user, pass string) (*Client, error) {
    c := &Client{
        BaseURL: baseURL,
        Username: user,
        Password: pass,
        HTTP: &http.Client{Timeout: 10 * time.Second},
    }
    return c, c.login()
}

func (c *Client) login() error {
    body, _ := json.Marshal(map[string]string{
        "username": c.Username,
        "password": c.Password,
    })
    resp, err := c.HTTP.Post(c.BaseURL+"/api/auth/login",
        "application/json", bytes.NewReader(body))
    if err != nil { return err }
    defer resp.Body.Close()
    var out struct {
        Code int `json:"code"`
        Data struct{ Token string `json:"token"` } `json:"data"`
    }
    if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { return err }
    c.Token = out.Data.Token
    return nil
}

func (c *Client) Call(method, path string, body any) ([]byte, error) {
    var rdr io.Reader
    if body != nil {
        b, _ := json.Marshal(body)
        rdr = bytes.NewReader(b)
    }
    do := func() (*http.Response, error) {
        req, _ := http.NewRequest(method, c.BaseURL+path, rdr)
        req.Header.Set("Authorization", "Bearer "+c.Token)
        if body != nil {
            req.Header.Set("Content-Type", "application/json")
        }
        return c.HTTP.Do(req)
    }
    resp, err := do()
    if err != nil { return nil, err }
    if resp.StatusCode == 401 {
        resp.Body.Close()
        if err := c.login(); err != nil { return nil, err }
        resp, err = do()
        if err != nil { return nil, err }
    }
    defer resp.Body.Close()
    return io.ReadAll(resp.Body)
}

func main() {
    c, err := New("https://waf.example.com", "admin", "YOUR_PASSWORD")
    if err != nil { panic(err) }

    raw, err := c.Call("GET", "/api/guard/domains", nil)
    if err != nil { panic(err) }
    fmt.Println(string(raw))
}

相关文档


Cloud WAF · 示例覆盖 curl / Python / Go 三语言,可直接复制运行