> For the complete documentation index, see [llms.txt](https://www.axisnow.io/zh/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.axisnow.io/zh/docs/guide/authn-authz.md).

# 保护对外 API 和 URL 鉴权

使用 AxisNow 在边缘校验 JWT 与自定义凭据并拦截非法请求

认证授权插件适合**保护对外 API、资源防盗用、零误伤防 CC 攻击**等场景。本文介绍我们用它保护自身 API 的实践，并演示自定义鉴权等典型用法。

## 认证授权插件 <a href="#what-is-auth-plugin" id="what-is-auth-plugin"></a>

对外开放的接口和资源，首先要确认请求方的身份和权限：API 要校验令牌，图片、视频、下载链接这类资源也要防止盗用。AxisNow 把这道认证放在边缘完成，由数据面的[认证与授权](/zh/docs/edge/policies/authn-authz.md)插件承担。请求进入边缘后，它完成两项工作：

* **认证：**&#x6821;验请求携带的凭据（JWT，或您自定义的逻辑），确认请求方的身份。
* **授权：**&#x7528;规则决定这个身份能否访问，放行或拒绝。

<figure><img src="https://3062891322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKDgGNU6JXG7cqYCk2aCz%2Fuploads%2Fgit-blob-e65aeffa1e0f428eeb2e1b2d3633e7379f49d94f%2Fimage%20(310).png?alt=media" alt=""><figcaption></figcaption></figure>

它做的是边缘的前置验证：确认身份、按规则决定能否访问某个资源，把非法与越权请求拦在源站之前。认证方式本文涉及两种：

* **JWT**：API、服务与合作方常用，用公钥校验令牌签名（支持公钥 / JWKS / OIDC）；
* **自定义认证**：一段可编程函数，承接 HMAC、私有令牌、防盗链等非标准鉴权，内置方式无法覆盖的场景由它处理。

只为需要保护的资源配置规则，未命中规则的请求不做认证、直接放行；命中后先认证、再授权，评估顺序和校验细节见[工作原理](/zh/docs/edge/policies/authn-authz/how-it-works.md)。

## API 鉴权：我们的实践 <a href="#api-authentication-in-practice" id="api-authentication-in-practice"></a>

AxisNow 是 API-first 的产品，所有能力都通过 API 交付，最主要的用法是用 JWT 保护这些 API，确保只有携带合法令牌的调用才能通过。配置分两步：

1. **‍创建** **JWT 认证方式：**&#x6307;定边缘从哪里取令牌、用什么校验签名，配置如下项目：

   * JWT 令牌位置：HTTP 请求头
   * 请求头：Authorization
   * 凭据配置：JWT 校验公钥
   * 签名算法：ES256
   * JWT 校验公钥

   <figure><img src="https://3062891322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKDgGNU6JXG7cqYCk2aCz%2Fuploads%2Fgit-blob-0b38cd749be6d2e334e50ba1b3119d896ef5e3bf%2Fimage%20(312).png?alt=media" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**公钥从哪里来？**

JWT 由签发方（您自己的鉴权服务或 IdP）用私钥签名，公钥是可以公开的那一半。填入公钥后边缘即可验签，私钥始终留在签发方，不接触边缘。签发方若提供 JWKS 或 OIDC 发现端点，也可以直接填端点地址，由边缘定期拉取公钥；令牌若用 JWE 加密，则先解密再校验。
{% endhint %}

2. **配置授权规则：**&#x5339;配要保护的资源（api.axisnow\.io）、强制认证、引用这个认证方式。授权默认动作设为「允许」，JWT 认证通过即放行，不需要再写授权子规则。

<figure><img src="https://3062891322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKDgGNU6JXG7cqYCk2aCz%2Fuploads%2Fgit-blob-e513cf46de978e0dbb79e28886acee507fd92e9a%2Fimage%20(313).png?alt=media" alt=""><figcaption></figcaption></figure>

配置完成后，边缘用这把公钥按 ES256 校验令牌签名：签名有效即认证通过、放行；签名无效的请求在认证阶段即被拒绝，不会到达源站。我们目前只做到这一层，令牌合法即放行；如需精细化授权，按 `aud`、`role` 等 claim 进一步限定谁能调用什么，在授权子规则里增加条件即可。

## 更多典型场景 <a href="#more-use-cases" id="more-use-cases"></a>

我们主要用 JWT 验证 API 请求，但插件的能力不止于此，借助自定义认证可以承接各种非标准鉴权。下面几种常见用法不一定出自我们自身的业务，但都基于同一套机制。

### 防盗用（Token 鉴权） <a href="#token-authentication" id="token-authentication"></a>

图片、视频、安装包这类资源，地址不加保护，一旦泄露就会被盗链，消耗源站带宽。常见做法是为链接附加签名和过期时间，即 CDN 领域常说的 Token 鉴权或 URL 鉴权。

链接由您的后端在下发时生成，形式如 `https://cdn.example.com/video/abc.mp4?sig=<签名>&exp=<过期时间戳>`。签名用一个只有您和边缘知道的密钥计算，算法和主流 CDN 一致：

```
sig = HMAC-SHA256(密钥, 路径 + "|" + exp)
```

边缘侧的校验用一段认证代码完成，按同样的算法重算签名、核对时效：

```lua
-- 防盗链：校验签名与过期时间
local SECRET = "replace-with-your-own-secret"

function handle(ctx)
    -- 查询参数可能缺失、也可能是无值的 boolean，先取值再判类型
    local sig = ctx.request.query:get("sig")
    local exp = tonumber(ctx.request.query:get("exp"))
    if type(sig) ~= "string" or not exp then
        return auth.result({ verified = false })
    end

    -- 链接过期即拒绝（time.now() 是带小数的秒，先取整）
    if math.floor(time.now()) > exp then
        return auth.result({ verified = false })
    end

    -- 用同样的密钥和算法重算签名，再做恒定时间比对
    local expected = crypto.hmac("sha256", SECRET, ctx.request.path .. "|" .. tostring(exp))
    if not expected or not crypto.secure_equal(sig, expected) then
        return auth.result({ verified = false })
    end

    return auth.result({ verified = true })
end
```

### 自定义认证 <a href="#custom-authentication" id="custom-authentication"></a>

防盗链就是自定义认证的一个用法。实际业务中还有很多非标准鉴权：HMAC 签名、私有令牌、时间戳加随机数，甚至完全自研的方案。内置方式无法逐一覆盖，这类场景用自定义认证函数处理。

自定义认证函数运行在[边缘运行时](/zh/docs/edge/policies/edge-runtime.md)中，这是边缘上的一个轻量 Lua 沙箱，可以用它实现各种鉴权逻辑：读取请求的方法、路径、头与参数，做签名校验、时效判断，最后返回放行或拒绝，上面的防盗链代码就是一个完整的例子。编辑器内置了一批参考示例代码，覆盖常见的标准与事实标准方案：HTTP Message Signatures（RFC 9421）、JWS（RFC 7515），以及 Webhook 签名（Stripe / GitHub 风格）、AWS Signature V4 等，供您参考。

<figure><img src="https://3062891322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKDgGNU6JXG7cqYCk2aCz%2Fuploads%2Fgit-blob-c38964ef8e5bf6be8d090f0b8f317c1e3c609e26%2Fimage%20(314).png?alt=media" alt=""><figcaption></figcaption></figure>

### 防 CC 攻击（零误伤） <a href="#cc-attack-protection" id="cc-attack-protection"></a>

CC 攻击用海量请求压垮源站。只要接口要求可校验的凭据，这类流量就很容易拦截。以上面两种用法为例：JWT 保护的 API，未携带令牌、令牌伪造或过期的请求在 ES256 验签这一步即被拒绝，不会到达源站；防盗链链接同理，签名不符或已过期的请求在 HMAC 校验时即被拒绝。放行只取决于凭据是否有效，合法调用不受任何影响，不会像按 IP 限速那样误伤正常用户；来源再分散、IP 再怎么轮换也没有意义，因为它们无法伪造出合法凭据。

认证只判断凭据真伪，剩下两种情况需要再加一层。一种是攻击者持有合法凭据并高频调用，认证会放行，这时交给[限速](/zh/docs/edge/policies/rate-limiting.md)：按认证识别出的身份限制频率。注意强制认证的规则默认绕过速率控制，要先在规则上关闭它。另一种是同一来源反复试错，在规则的**附加控制**里开启**认证失败封禁**，失败次数超过阈值的 IP 会被临时封禁，后续请求不再逐个校验，避免消耗边缘性能。

需要留意的是，授权拒绝不计入封禁：身份合法、只是无权限而被拒的请求，不算认证失败，也就不会触发封禁，避免误封正常用户。细节见[工作原理 › 附加控制](/zh/docs/edge/policies/authn-authz/how-it-works.md#controls)。

<figure><img src="https://3062891322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKDgGNU6JXG7cqYCk2aCz%2Fuploads%2Fgit-blob-e28995c3c3bc9d401dd0f841715ef2f927b69f2b%2Fimage%20(315).png?alt=media" alt=""><figcaption></figcaption></figure>

## 上线前测试 <a href="#test-before-go-live" id="test-before-go-live"></a>

配置容易出错，用线上流量试错代价过高。控制台内置了集成测试：粘贴一个 JWT 令牌，或直接构造一个请求（URL、请求头、Cookie），运行后即可看到认证结果、命中的规则、日志和失败原因，确认无误再上线。这一步对自定义认证尤其有用，确认校验逻辑通过测试再发布。

<figure><img src="https://3062891322-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKDgGNU6JXG7cqYCk2aCz%2Fuploads%2Fgit-blob-2f8a724c7f29e987566a6e29538ba121d0220e27%2Fimage%20(316).png?alt=media" alt=""><figcaption></figcaption></figure>

## 后续扩展方向 <a href="#future-extensions" id="future-extensions"></a>

认证授权插件被设计成一个可持续扩展的框架：新增一种认证方式只需增加一项，授权规则与下游集成保持不变。围绕“边缘上的机器 / 服务 / API 认证”这条主线，后续计划：

* **分析和可观察性：**&#x8FD0;行时的关键指标数据，支持日常运营分析或故障排查。
* **更多认证方式**：mTLS 与工作负载身份、API Key / Basic，以及转发到自建鉴权服务的外部委托；
* **更完善的密钥轮转：**&#x5728;现有 JWKS 自动更新、多公钥并存的基础上，进一步支持轮转的灰度与更平滑的过渡。

常见问题见插件文档的[常见问题](/zh/docs/edge/policies/authn-authz/faq.md)。

我们非常乐意听取您对产品和体验的反馈，您可以加入[社区电报群组](https://t.me/AxisNowGroupZh)。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://www.axisnow.io/zh/docs/guide/authn-authz.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
