add-request-protection

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Add Arcjet Protection to a Route

为路由添加Arcjet防护

Add runtime security to a route handler using Arcjet. This skill guides you through setting up the CLI, detecting the framework, configuring rules, and verifying protection.
使用Arcjet为路由处理器添加运行时安全防护。本技能将引导你完成CLI设置、框架检测、规则配置以及防护验证的全流程。

Reference

参考文档

Read https://docs.arcjet.com/llms.txt for comprehensive SDK documentation covering all frameworks, rule types, and configuration options.
阅读 https://docs.arcjet.com/llms.txt 获取涵盖所有框架、规则类型和配置选项的完整SDK文档。

Step 0: Set Up the Arcjet CLI

步骤0:设置Arcjet CLI

The Arcjet CLI is the primary tool for authenticating, managing sites, configuring remote rules, and verifying protection. Install it if not already available:
bash
undefined
Arcjet CLI是进行认证、站点管理、远程规则配置和防护验证的核心工具。如果尚未安装,请按以下方式安装:
bash
undefined

Via npx (no install required)

通过npx运行(无需安装)

npx @arcjet/cli --help
npx @arcjet/cli --help

Or install globally via npm

或通过npm全局安装

npm install -g @arcjet/cli
npm install -g @arcjet/cli

Or via Homebrew

或通过Homebrew安装

brew install arcjet
undefined
brew install arcjet
undefined

Authenticate

认证

bash
arcjet auth login
Opens the browser for authentication. Check status with
arcjet auth status
.
bash
arcjet auth login
此命令将打开浏览器进行认证。可使用
arcjet auth status
检查认证状态。

Site & Key Setup

站点与密钥设置

bash
undefined
bash
undefined

List your teams

列出你的团队

arcjet teams list
arcjet teams list

List sites for a team

列出指定团队下的站点

arcjet sites list --team-id <team-id>
arcjet sites list --team-id <team-id>

Create a new site

创建新站点

arcjet sites create --team-id <team-id> --name "My App" --confirm
arcjet sites create --team-id <team-id> --name "My App" --confirm

Get the SDK key for a site

获取指定站点的SDK密钥

arcjet sites get-key --site-id <site-id>

Add the key to your environment file (`.env.local` for Next.js/Astro, `.env` for others) as `ARCJET_KEY`.
arcjet sites get-key --site-id <site-id>

将密钥添加到你的环境文件中(Next.js/Astro使用`.env.local`,其他框架使用`.env`),命名为`ARCJET_KEY`。

Step 1: Detect the Framework

步骤1:检测框架

Check the project for framework indicators:
  • package.json
    dependencies:
    next
    ,
    express
    ,
    fastify
    ,
    @nestjs/core
    ,
    @sveltejs/kit
    ,
    hono
    ,
    @remix-run/node
    ,
    react-router
    ,
    astro
    ,
    nuxt
  • bun.lockb
    or
    bun.lock
    → Bun runtime
  • deno.json
    → Deno runtime
  • pyproject.toml
    or
    requirements.txt
    with
    fastapi
    or
    flask
    → Python
Select the correct Arcjet adapter package:
FrameworkPackage
Next.js
@arcjet/next
Express / Node.js / Hono
@arcjet/node
Fastify
@arcjet/fastify
NestJS
@arcjet/nest
SvelteKit
@arcjet/sveltekit
Remix
@arcjet/remix
React Router
@arcjet/react-router
Astro
@arcjet/astro
Bun
@arcjet/bun
Deno
npm:@arcjet/deno
Python (FastAPI/Flask)
arcjet
(pip)
检查项目中的框架标识:
  • package.json
    依赖项:
    next
    express
    fastify
    @nestjs/core
    @sveltejs/kit
    hono
    @remix-run/node
    react-router
    astro
    nuxt
  • bun.lockb
    bun.lock
    → Bun运行时
  • deno.json
    → Deno运行时
  • pyproject.toml
    requirements.txt
    中包含
    fastapi
    flask
    → Python
选择正确的Arcjet适配器包:
框架包名称
Next.js
@arcjet/next
Express / Node.js / Hono
@arcjet/node
Fastify
@arcjet/fastify
NestJS
@arcjet/nest
SvelteKit
@arcjet/sveltekit
Remix
@arcjet/remix
React Router
@arcjet/react-router
Astro
@arcjet/astro
Bun
@arcjet/bun
Deno
npm:@arcjet/deno
Python (FastAPI/Flask)
arcjet
(pip)

Step 2: Check for Existing Arcjet Setup

步骤2:检查现有Arcjet配置

Search the project for an existing shared Arcjet client file (commonly
lib/arcjet.ts
,
src/lib/arcjet.ts
,
lib/arcjet.py
, or similar).
If no client exists:
  1. Install the correct adapter package.
  2. Check if
    ARCJET_KEY
    is set in the environment file (
    .env.local
    for Next.js/Astro,
    .env
    for others). If not, obtain the key in this priority order:
    1. CLI (preferred): Run
      arcjet sites get-key --site-id <site-id>
      (requires
      arcjet auth login
      first — see Step 0)
    2. MCP: If the Arcjet MCP server is connected, use
      list-teams
      list-sites
      get-site-key
    3. Manual (last resort): Add a placeholder and tell the user to get a key from https://app.arcjet.com
    • Also add
      ARCJET_ENV=development
      to the env file
  3. Create a shared client file with
    shield()
    as the base rule. This file should export the Arcjet instance for reuse across routes with
    withRule()
    .
If a client already exists: Import it. Do not create a new instance.
在项目中搜索已有的共享Arcjet客户端文件(通常为
lib/arcjet.ts
src/lib/arcjet.ts
lib/arcjet.py
或类似文件)。
如果不存在客户端文件:
  1. 安装正确的适配器包。
  2. 检查环境文件中是否已设置
    ARCJET_KEY
    (Next.js/Astro使用
    .env.local
    ,其他框架使用
    .env
    )。如果未设置,请按以下优先级获取密钥:
    1. CLI(推荐): 运行
      arcjet sites get-key --site-id <site-id>
      (需先执行
      arcjet auth login
      ——参见步骤0)
    2. MCP: 如果已连接Arcjet MCP服务器,使用
      list-teams
      list-sites
      get-site-key
      流程获取
    3. 手动(最后手段): 添加占位符并告知用户从https://app.arcjet.com获取密钥
    • 同时在环境文件中添加
      ARCJET_ENV=development
  3. 创建一个共享客户端文件,以
    shield()
    作为基础规则。该文件应导出Arcjet实例,以便在多个路由中通过
    withRule()
    复用。
如果客户端文件已存在: 直接导入该实例,不要创建新实例。

Step 3: Choose Protection Rules

步骤3:选择防护规则

Select rules based on the route's purpose. If the user specified what they want, use that. Otherwise, infer from context:
Route typeRecommended rules
Public API endpoint
shield()
+
detectBot()
+
slidingWindow()
(use
fixedWindow()
only if hard per-window caps are needed)
Form handler / signup
shield()
+
validateEmail()
+
slidingWindow()
Authentication endpoint
shield()
+
slidingWindow()
(strict, low limits)
AI / LLM endpoint
shield()
+
detectBot()
+
tokenBucket()
+ content filtering
Webhook receiver
shield()
+ filter rules for allowed IPs
General server route
shield()
+
detectBot()
For routes that need to detect sophisticated bots (headless browsers, advanced scrapers) — especially form submissions, login/signup pages, and other abuse-prone endpoints — recommend adding Arcjet advanced signals. This is a browser-based detection system using client-side telemetry that complements server-side
detectBot()
rules. See https://docs.arcjet.com/bot-protection/advanced-signals for setup instructions.
Apply route-specific rules using
withRule()
on the shared instance — do not modify the shared instance directly.
根据路由用途选择规则。如果用户已明确需求,则按用户要求选择;否则根据上下文推断:
路由类型推荐规则
公开API端点
shield()
+
detectBot()
+
slidingWindow()
(仅在需要严格的窗口上限时使用
fixedWindow()
表单处理器/注册页面
shield()
+
validateEmail()
+
slidingWindow()
认证端点
shield()
+
slidingWindow()
(严格限制,低阈值)
AI/LLM端点
shield()
+
detectBot()
+
tokenBucket()
+ 内容过滤
Webhook接收器
shield()
+ 允许IP的过滤规则
通用服务器路由
shield()
+
detectBot()
对于需要检测复杂机器人(无头浏览器、高级爬虫)的路由——尤其是表单提交、登录/注册页面和其他易受滥用的端点——建议添加Arcjet高级信号。这是一个基于浏览器的检测系统,使用客户端遥测数据补充服务器端
detectBot()
规则。设置说明请参见https://docs.arcjet.com/bot-protection/advanced-signals。
通过在共享实例上调用
withRule()
应用路由特定规则——不要直接修改共享实例。

Step 4: Add Protection to the Handler

步骤4:为处理器添加防护

Call
protect()
inside the route handler (not in middleware), only once per request, passing the framework's request object directly. For Next.js pages/server components: use
import { request } from "@arcjet/next"
then
const req = await request()
.
Use this pattern:
typescript
const decision = await aj.protect(req);

if (decision.isDenied()) {
  if (decision.reason.isRateLimit()) {
    return Response.json(
      { error: "Too many requests" },
      { status: 429 },
    );
  }
  if (decision.reason.isBot() || decision.reason.isShield() || decision.reason.isFilterRule()) {
    return Response.json(
      { error: "Forbidden" },
      { status: 403 },
    );
  }
  if (decision.reason.isSensitiveInfo()) {
    return Response.json(
      { error: "Bad request" },
      { status: 400 },
    );
  }
}

// Arcjet fails open — log errors but allow the request
if (decision.isErrored()) {
  console.warn("Arcjet error:", decision.reason.message);
}

// Proceed with route handler logic...
Adapt the response format to your framework (e.g.,
res.status(429).json(...)
for Express,
JsonResponse
for Django).
在路由处理器内部调用
protect()
,每个请求仅调用一次,直接传入框架的请求对象。对于Next.js页面/服务器组件:使用
import { request } from "@arcjet/next"
,然后执行
const req = await request()
使用以下模式:
typescript
const decision = await aj.protect(req);

if (decision.isDenied()) {
  if (decision.reason.isRateLimit()) {
    return Response.json(
      { error: "Too many requests" },
      { status: 429 },
    );
  }
  if (decision.reason.isBot() || decision.reason.isShield() || decision.reason.isFilterRule()) {
    return Response.json(
      { error: "Forbidden" },
      { status: 403 },
    );
  }
  if (decision.reason.isSensitiveInfo()) {
    return Response.json(
      { error: "Bad request" },
      { status: 400 },
    );
  }
}

// Arcjet采用故障开放模式——记录错误但允许请求通过
if (decision.isErrored()) {
  console.warn("Arcjet error:", decision.reason.message);
}

// 继续执行路由处理器逻辑...
根据框架调整响应格式(例如,Express使用
res.status(429).json(...)
,Django使用
JsonResponse
)。

Step 5: Verify with the CLI

步骤5:使用CLI验证

After adding protection, use the CLI to verify decisions are firing correctly. This creates a feedback loop: start the app, hit the route, inspect decisions, adjust if needed.
添加防护后,使用CLI验证规则是否正确触发。这形成一个反馈循环:启动应用、访问路由、检查决策、按需调整。

1. Start Watching

1. 开始监控

In a separate terminal, stream live request decisions:
bash
arcjet watch --site-id <site-id>
This polls for new decisions and prints them as they arrive. Use
--conclusion DENY
to filter to denials only, or
--interval 2
for faster polling.
在另一个终端中,流式传输实时请求决策:
bash
arcjet watch --site-id <site-id>
该命令会轮询新决策并在到达时打印。使用
--conclusion DENY
仅过滤拒绝请求,或使用
--interval 2
加快轮询速度。

2. Hit the Protected Route

2. 访问受防护的路由

Start the app and send requests to the protected route. Each request should produce a decision visible in the watch output.
启动应用并向受防护的路由发送请求。每个请求都会生成一个决策,可在监控输出中查看。

3. Inspect Decisions

3. 检查决策

If a decision doesn't match expectations:
bash
undefined
如果决策不符合预期:
bash
undefined

List recent requests (filter to denials)

列出近期请求(过滤拒绝请求)

arcjet requests list --site-id <site-id> --conclusion DENY --limit 10
arcjet requests list --site-id <site-id> --conclusion DENY --limit 10

Get full details for a specific request

获取特定请求的完整详情

arcjet requests details --site-id <site-id> --request-id <request-id>
arcjet requests details --site-id <site-id> --request-id <request-id>

Plain-English explanation of why a request was allowed/denied

用通俗易懂的语言解释请求被允许/拒绝的原因

arcjet requests explain --site-id <site-id> --request-id <request-id>
undefined
arcjet requests explain --site-id <site-id> --request-id <request-id>
undefined

4. Adjust and Repeat

4. 调整并重复测试

If rules aren't firing as expected, adjust the code and re-test. Use
arcjet watch
to confirm each change produces the expected decisions.
The Arcjet dashboard at https://app.arcjet.com is also available for visual inspection.
如果规则未按预期触发,调整代码并重新测试。使用
arcjet watch
确认每次修改都能产生预期的决策。

Step 6: Manage Remote Rules via CLI (Optional)

步骤6:通过CLI管理远程规则(可选)

Remote rules apply globally to all requests for a site and can be managed without code changes or redeployment. Supported types:
rate_limit
,
bot
,
shield
,
filter
.
bash
undefined
远程规则全局应用于站点的所有请求,无需修改代码或重新部署即可管理。支持的规则类型:
rate_limit
bot
shield
filter
bash
undefined

Create a rule (always starts in DRY_RUN)

创建规则(初始为DRY_RUN模式)

arcjet rules create --site-id <site-id> --type rate_limit --max 100 --window 60 --confirm arcjet rules create --site-id <site-id> --type shield --confirm arcjet rules create --site-id <site-id> --type bot --deny CATEGORY:SEARCH_ENGINE --confirm
arcjet rules create --site-id <site-id> --type rate_limit --max 100 --window 60 --confirm arcjet rules create --site-id <site-id> --type shield --confirm arcjet rules create --site-id <site-id> --type bot --deny CATEGORY:SEARCH_ENGINE --confirm

Check what a dry-run rule would block

检查试运行规则会拦截哪些请求

arcjet analyze dry-run-impact --site-id <site-id>
arcjet analyze dry-run-impact --site-id <site-id>

Promote to LIVE once verified

验证后升级为LIVE模式

arcjet rules promote --site-id <site-id> --rule-id <rule-id> --confirm
arcjet rules promote --site-id <site-id> --rule-id <rule-id> --confirm

List / update / delete rules

列出/更新/删除规则

arcjet rules list --site-id <site-id> arcjet rules update --site-id <site-id> --rule-id <rule-id> --max 200 --confirm arcjet rules delete --site-id <site-id> --rule-id <rule-id> --confirm
undefined
arcjet rules list --site-id <site-id> arcjet rules update --site-id <site-id> --rule-id <rule-id> --max 200 --confirm arcjet rules delete --site-id <site-id> --rule-id <rule-id> --confirm
undefined

Step 7: Traffic Analysis

步骤7:流量分析

Use the CLI to monitor traffic patterns and investigate issues:
bash
undefined
使用CLI监控流量模式并排查问题:
bash
undefined

Full security briefing (traffic, denials, quota, active rules)

完整安全简报(流量、拒绝请求、配额、激活规则)

arcjet briefing --site-id <site-id>
arcjet briefing --site-id <site-id>

Traffic analysis over 14 days

14天流量分析

arcjet analyze traffic --site-id <site-id> --days 14
arcjet analyze traffic --site-id <site-id> --days 14

Detect anomalies (spikes, geographic shifts, new threats)

检测异常(流量峰值、地域变化、新威胁)

arcjet analyze anomalies --site-id <site-id>
arcjet analyze anomalies --site-id <site-id>

Investigate a specific IP

调查特定IP

arcjet analyze ip --site-id <site-id> --ip 1.2.3.4
undefined
arcjet analyze ip --site-id <site-id> --ip 1.2.3.4
undefined

Common Mistakes to Avoid

需避免的常见错误

  • Creating a new Arcjet instance per request (causes connection overhead)
  • Using Arcjet in Next.js middleware (fires on every request, no route context)
  • Calling
    protect()
    multiple times in one request (double-counts rate limits)
  • Hardcoding
    ARCJET_KEY
    instead of using environment variables
  • Using
    app.use()
    as Express middleware instead of per-route protection
  • 每个请求创建新的Arcjet实例(会导致连接开销)
  • 在Next.js中间件中使用Arcjet(会在每个请求触发,无路由上下文)
  • 在一个请求中多次调用
    protect()
    (会重复计算速率限制)
  • 硬编码
    ARCJET_KEY
    而非使用环境变量
  • 在Express中使用
    app.use()
    作为中间件而非按路由添加防护

CLI Quick Reference

CLI快速参考

TaskCommand
Install/run CLI
npx @arcjet/cli
or
brew install arcjet
Authenticate
arcjet auth login
Check auth status
arcjet auth status
List teams
arcjet teams list
List sites
arcjet sites list --team-id <id>
Create site
arcjet sites create --team-id <id> --name "Name" --confirm
Get SDK key
arcjet sites get-key --site-id <id>
Watch live requests
arcjet watch --site-id <id>
List requests
arcjet requests list --site-id <id>
Explain a decision
arcjet requests explain --site-id <id> --request-id <id>
Create rule (DRY_RUN)
arcjet rules create --site-id <id> --type <type> ...
List rules
arcjet rules list --site-id <id>
Promote to LIVE
arcjet rules promote --site-id <id> --rule-id <id> --confirm
Security briefing
arcjet briefing --site-id <id>
Analyze traffic
arcjet analyze traffic --site-id <id>
任务命令
安装/运行CLI
npx @arcjet/cli
brew install arcjet
认证
arcjet auth login
检查认证状态
arcjet auth status
列出团队
arcjet teams list
列出站点
arcjet sites list --team-id <id>
创建站点
arcjet sites create --team-id <id> --name "Name" --confirm
获取SDK密钥
arcjet sites get-key --site-id <id>
监控实时请求
arcjet watch --site-id <id>
列出请求
arcjet requests list --site-id <id>
解释决策原因
arcjet requests explain --site-id <id> --request-id <id>
创建规则(DRY_RUN模式)
arcjet rules create --site-id <id> --type <type> ...
列出规则
arcjet rules list --site-id <id>
升级为LIVE模式
arcjet rules promote --site-id <id> --rule-id <id> --confirm
安全简报
arcjet briefing --site-id <id>
流量分析
arcjet analyze traffic --site-id <id>

Global Flags

全局标志

All commands support:
  • --output text|json
    — output format (default: text on TTY, json otherwise)
  • --fields <list>
    — comma-separated fields to include in JSON output
  • --no-color
    — disable ANSI colors (also honors
    NO_COLOR
    env var)
  • --timeout <duration>
    — max execution time (e.g.
    30s
    ,
    5m
    ; 0 disables)
所有命令支持:
  • --output text|json
    — 输出格式(默认:终端输出为text,其他情况为json)
  • --fields <list>
    — JSON输出中包含的字段列表(逗号分隔)
  • --no-color
    — 禁用ANSI颜色(同时支持
    NO_COLOR
    环境变量)
  • --timeout <duration>
    — 最大执行时间(例如
    30s
    5m
    ;0表示无限制)

Exit Codes

退出码

CodeMeaning
0Success
1General error (unknown command, API failure, network error)
2Authentication error (not logged in, token expired)
3Input validation error (invalid ID, value out of range)
4Confirmation required (mutation needs
--confirm
)
代码含义
0成功
1通用错误(未知命令、API失败、网络错误)
2认证错误(未登录、令牌过期)
3输入验证错误(无效ID、值超出范围)
4需要确认(修改操作需添加
--confirm