边缘安全加速平台 EO Agent 鉴权

Agent 应用通常会调用模型、工具,如果没有登录鉴权,任何人都可以直接访问 Agent 接口,可能带来以下问题。

相关产品
边缘安全加速平台 EO 产品页,含版本规格、价格与购买入口。

·资源被滥用:未登录用户也能消耗 LLM 和工具调用额度。

·接口容易被绕过调用:攻击者可以跳过前端页面,直接请求 /agents/* 等接口。

这篇档以 实际项目 为例,说明如何基于 Makers 平台能力搭建登录鉴权流程:由 Cloud Functions 负责登录注册和 JWT 签发,由平台中间件在边缘节点提前拦截未登录请求。

一、项目主要文件与职责

文件 / 模块 主要职责
middleware.js 平台中间件,命中受保护路径时先校验 Cookie JWT,失败直接 401,成功 next()。
cloud-functions/auth/* 登录、注册、登出、查询当前用户,负责校验账号密码并签发 JWT。
agents/chat/index.ts Agent 示例入口,演示鉴权、流式返回。
db/migrations/users.sql Neon 数据库表结构。

二、核心模型

用户浏览器 │ │ 登录 / 注册 ▼cloud-functions/auth/* │ 校验账号密码 │ 写入 / 查询 Neon │ 签发 JWT ▼浏览器保存 HttpOnly Cookie: jwt_token │ │ 调用 Agent ▼middleware.js │ 先验 Cookie 里的 JWT │ 无效:直接 401 │ 有效:next() 透传 ▼Agent Runtime │ 再次 requireAuth(context) │ ▼返回 SSE / Agent 响应

三、JWT 内容约定

interface JwtPayload { sub: string; // users.id,UUID v4 username: string; // 用户名 iat: number; // 签发时间,秒级时间戳 exp: number; // 过期时间,秒级时间戳}

四、登录 / 注册流程

浏览器 │ │ ① POST /auth/login 或 /auth/register ▼middleware.js │ │ ② /auth/* 不在 matcher 中,直接放行 ▼cloud-functions/auth/* │ │ ③ 校验 username / password │ ④ 查询或写入 Neon users 表 │ ⑤ bcrypt 校验或生成 password_hash │ ⑥ 使用 JWT_SECRET 签发 JWT ▼浏览器 │ │ ⑦ Set-Cookie: jwt_token=… ▼登录完成

关键点:

·/auth/login、/auth/register 必须是公开接口。

·它们不要放进 middleware.config.matcher。

·登录成功后只通过 HttpOnly Cookie 保存 token,不把 token 暴露给前端 JS。

五、Agent 调用流程

浏览器 │ │ ⑧ POST /chat,自动携带 Cookie: jwt_token=… ▼middleware.js │ │ ⑨ Web Crypto 校验 JWT │ 失败:401 │ 成功:next() ▼Agent Runtime │ │ ⑩ requireAuth(context) 再验一次 JWT ▼浏览器 │ │ ⑪ SSE 流式返回 Agent 响应

关键点:

·中间件验签成功后只透传原请求。

·Agent 自己从 Cookie 读取 JWT,并独立验签(可选)。

六、平台中间件关键实现

文件:middleware.js

职责:命中受保护路径 → 校验 Cookie JWT → 失败 401 / 成功 next()

七、配置受保护路径

export const config = { matcher: [ '/chat/:path*', '/stop/:path*', '/history/:path*', '/agents/:path*', ],};

注意:

·matcher 是中间件保护范围的唯一来源。

·/auth/* 不要加入 matcher。

·静态资源、前端页面路由一般也不需要加入 matcher。

八、主逻辑

export async function middleware(context) { const { request, next, env } = context; const token = readCookie(request.headers, 'jwt_token'); if (!token) return unauthorized('no auth cookie'); try { await verifyJwt(token, env.JWT_SECRET); } catch (e) { return unauthorized(e.message || 'verify failed'); } return next();}

九、验签要点

中间件运行在边缘 V8 环境,使用 Web Crypto:

const key = await crypto.subtle.importKey( 'raw', utf8ToBytes(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify'],);

验签时必须检查:

检查项 目的
token 是否是三段式 防止 malformed token。
header.alg === 'HS256' 防 alg=none 和算法混淆。
HMAC 签名是否一致 确认 token 未被篡改。
payload.exp 是否过期 防止旧 token 长期有效。

十、Cloud Functions 关键实现

目录:cloud-functions/

职责:注册 / 登录 / 当前用户信息 / 登出

十一、文件结构

文件 作用
auth/register/index.ts 注册用户,写入 Neon,颁发 JWT。
auth/login/index.ts 校验密码,颁发 JWT。
auth/user/index.ts 从 Cookie 判断当前登录用户。
auth/logout/index.ts 清空 Cookie。

十二、Agent 侧关键实现

文件示例:agents/chat/index.ts

十三、入口第一步验签(可选)

中间件的价值是早拒:在边缘节点挡掉未登录请求,减少 Agent Runtime、Sandbox、LLM 的成本。但中间件不是最终安全边界,你可以在 Agent 侧再做一次验签。

import { requireAuth, AuthError, unauthorizedResponse } from '../_jwt';export async function onRequest(context: any) { let auth; try { auth = requireAuth(context); } catch (e) { if (e instanceof AuthError) { return unauthorizedResponse(e.reason); } throw e; } // 从这里开始,才能执行 Agent 业务逻辑}

十四、数据库配置与实现

Neon 是 Serverless Postgres,此方案用它保存用户表,并通过 @neondatabase/serverless 以 HTTPS 方式访问,你也可以选择其它第三方数据库。

十五、配置步骤

1. 在 Neon 控制台 创建项目。

2. 获取连接串,格式类似如下:

postgresql://<user>:<password>@<host>/<db>?sslmode=require

3. 在 EdgeOne Makers 项目环境变量中配置:

变量 必填 说明
DATABASE_URL 是 Neon 连接串,建议带 ?sslmode=require。
JWT_SECRET 是 JWT 签名密钥,三层必须一致。

本地开发时,在 .env 中配置同名变量。

十六、数据库表结构

CREATE EXTENSION IF NOT EXISTS pgcrypto;CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), username VARCHAR(64) NOT NULL, password_hash VARCHAR(255) NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW());CREATE UNIQUE INDEX IF NOT EXISTS users_username_lower_uniq ON users (LOWER(username));

说明:

·id 由 Postgres gen_random_uuid() 自动生成。

·password_hash 只保存 bcrypt 哈希,不保存明文密码。

·LOWER(username) 唯一索引用于避免 Alice 和 alice 同时注册。

十七、接入步骤

如果你要把这套方案接到自己的 Agent 项目,按这个顺序做:

1. 创建 Neon 数据库,执行 db/migrations/users.sql;

2. 配置 DATABASE_URL、JWT_SECRET;

3. 复制 cloud-functions/auth/*、cloud-functions/_jwt.ts、cloud-functions/_db.ts、cloud-functions/_validate.ts;

4. 配置 middleware.js 的 matcher,覆盖所有受保护 Agent 路径;

5. 在每个 Agent 入口第一步加入 requireAuth(context)。

赞 (0)
上一篇 4天前
下一篇 4天前