SuperAPI AI 工具集

express-oauth2-jwt-bearer

安全与审计

查看项目

更新于 10-15 12:28

技能介绍

用途

express-oauth2-jwt-bearer 是 Auth0 提供的 Express 中间件,用于校验 Auth0 JWT Bearer 访问令牌。它按 RFC 6750 处理令牌提取、签名验证、受众(audience)与签发者(issuer)校验以及过期检查,让开发者专注于业务逻辑而非 JWT 解析。

主要能力

  • JWT Bearer 令牌校验中间件 auth(),令牌无效或缺失时返回 401。
  • 基于 scope 的访问控制:requiredScopes() 校验令牌是否包含全部所需 scope(缺失返回 403);scopeIncludesAny() 校验是否至少包含一个 scope。
  • 基于 claim 的校验:claimEquals()、claimIncludes()、claimCheck()(自定义校验函数)。
  • 支持 DPoP 绑定(通过 dpop 配置项)。
  • 校验成功后,req.auth 包含 payload(解码后的 JWT 载荷,如 sub、iss、aud、exp、permissions 等)、header(alg、typ、kid)和 token(原始 JWT 字符串)。
  • SDK 自动从环境变量 ISSUER_BASE_URL 和 AUDIENCE 读取配置,auth() 无需传参。

使用方式

前置条件:Node.js 18+(推荐 20+,bootstrap 脚本自动化需要 20+)、Express 4.x 或 5.x、npm 或 yarn、已配置 API(Resource Server)的 Auth0 账户;自动设置需 Auth0 CLI(npm install -g @auth0/auth0-cli)。

安装:

npm install express-oauth2-jwt-bearer

配置 .env:

ISSUER_BASE_URL=https://your-tenant.us.auth0.com
AUDIENCE=https://your-api-identifier

加载并应用中间件:

import 'dotenv/config'; // load .env before the SDK reads process.env
import { auth } from 'express-oauth2-jwt-bearer';

// Reads ISSUER_BASE_URL and AUDIENCE from the environment — no config needed
const checkJwt = auth();

app.use(checkJwt); // apply globally, or per-route

保护端点(全局或按路由):

// Global protection
app.use(checkJwt);

// Or per-route
app.get('/api/private', checkJwt, (req, res) => {
  res.json({ sub: req.auth.payload.sub });
});

添加 RBAC(可选):

import { auth, requiredScopes, claimIncludes } from 'express-oauth2-jwt-bearer';

app.get('/api/messages', checkJwt, requiredScopes('read:messages'), (req, res) => {
  res.json({ messages: [] });
});

注意:requiredScopes 只接受一个参数——空格分隔的字符串或数组。不要传入多个字符串参数:requiredScopes('read:msg', 'write:msg') 会静默忽略第一个之后的所有参数。应使用 requiredScopes('read:msg write:msg') 或 requiredScopes(['read:msg', 'write:msg'])。

验证集成:

node server.js
curl http://localhost:3000/api/private         # should return 401
curl -H "Authorization: Bearer <token>" http://localhost:3000/api/private  # should return 200

配置选项

  • issuerBaseURL(string):带 https:// 的完整签发者 URL。可选,默认取 ISSUER_BASE_URL 环境变量。
  • audience(string):Auth0 Dashboard 中的 API Identifier。可选,默认取 AUDIENCE 环境变量。
  • tokenSigningAlg(string):签名算法,默认 RS256;对称算法用 HS256。
  • authRequired(boolean):设为 false 使认证可选,默认 true。
  • clockTolerance(number):时钟偏差容忍秒数,无默认值。
  • dpop(DPoPOptions):DPoP 配置。

环境变量:ISSUER_BASE_URL(带 https:// 的完整签发者 URL,SDK 自动识别)、AUDIENCE(API Identifier,SDK 自动识别)。

适用场景

适用于由 SPA、移动应用、M2M 客户端调用的无状态 API。不适用于:带登录 UI 的服务端 Web 应用(Express 会话)应使用 auth0-express;Next.js 服务端认证应使用 auth0-nextjs;React/Angular/Vue SPA 应使用 auth0-react、auth0-angular、auth0-vue;React Native 或移动应用应使用 auth0-react-native、auth0-android、auth0-swift;ASP.NET Core Web API 应使用 auth0-aspnetcore-api;Go API 应使用 go-jwt-middleware;Python API(Flask/FastAPI)应使用 auth0-api-python;使用旧版 express-jwt 包的 Node.js API 应使用 express-jwt。

限制与常见错误

  • 在 Auth0 Dashboard 创建了 Application 而非 API:令牌校验失败、受众错误。应在 Auth0 Dashboard → APIs 创建新的 API(Resource Server)。
  • 受众与 API Identifier 不完全匹配:401 Unauthorized — "Audience mismatch"。应复制 Auth0 Dashboard → APIs 中精确的 API Identifier 字符串。
  • ISSUER_BASE_URL 缺少 https:// 协议:启动时报 Error: Invalid URL。ISSUER_BASE_URL 必须是完整签发者 URL。
  • RBAC 检查 scope claim 而非 permissions:始终返回 403 或忽略权限。scope 用 requiredScopes(),Auth0 RBAC 权限 claim 用 claimIncludes('permissions', 'read:data')。
  • CORS 未在认证中间件之前配置:预检 OPTIONS 请求返回 401。应在中间件链中把 cors() 放在 auth() 之前。
  • .env 文件未加载:domain/audience 为 undefined。应在入口文件顶部添加 import 'dotenv/config'。
  • 源码中硬编码 domain/audience(含 process.env.X || 'literal' 回退):密钥提交到源码、安全审查失败。应把值放入 .env(ISSUER_BASE_URL / AUDIENCE),让 auth() 自动读取,不要字面量回退。
  • req.auth 为 undefined:TypeError: Cannot read properties of undefined。应确认 checkJwt 中间件在处理器之前运行。

SDK 架构

node-oauth2-jwt-bearer 单仓库包含三个包:express-oauth2-jwt-bearer(主包,Express 中间件,发布到 npm)、access-token-jwt(底层 JWT 验证工具,内部使用)、oauth2-bearer(RFC 6750 Bearer 令牌提取,内部使用)。实际只需安装并导入 express-oauth2-jwt-bearer。

测试参考

从 Auth0 Dashboard → APIs → 你的 API → Test 标签页获取测试令牌,然后:

# 1. Verify 401 on protected route (no token)
curl -v http://localhost:3000/api/private

# 2. Verify 200 with valid token
curl -H "Authorization: Bearer <paste-token-here>" http://localhost:3000/api/private

# 3. Verify 403 with valid token but missing scope
curl -H "Authorization: Bearer <paste-token-here>" http://localhost:3000/api/admin

# 4. Verify CORS preflight
curl -v -X OPTIONS http://localhost:3000/api/private \
  -H "Origin: http://localhost:5173" \
  -H "Access-Control-Request-Method: GET" \
  -H "Access-Control-Request-Headers: Authorization"

相关技能

auth0-express(带登录 UI 的 Express Web 应用,会话、Cookie)、auth0-nextjs(Next.js 服务端 Web 应用)、auth0-aspnetcore-api(.NET 的 BACKEND_API 参考实现)、go-jwt-middleware(Go API 的 JWT 中间件)、auth0-api-python(Python API 的 JWT 校验,Flask/FastAPI)、auth0-cli(从终端管理 Auth0 资源)。