SuperAPI AI 工具集

auth0-express

安全与审计

查看项目

更新于 10-15 14:34

技能介绍

用途

auth0-express 用于为 Express.js Web 应用添加基于会话的认证能力,底层集成 express-openid-connect。当需要为 Express 应用添加登录、登出或受保护路由时使用。

前置条件

  • 一个 Express.js 应用
  • 已配置的 Auth0 账户与应用
  • 若尚未完成 Auth0 设置,需先使用 auth0-quickstart skill

不适用场景

  • 单页应用:应使用 auth0-react、auth0-vue 或 auth0-angular 进行客户端认证
  • Next.js 应用:应使用 auth0-nextjs skill,它同时处理客户端与服务端
  • 移动应用:React Native/Expo 应使用 auth0-react-native
  • 无状态 API:应使用 JWT 验证中间件而非基于会话的认证
  • 微服务:服务间认证应使用 JWT 验证

快速开始流程

1. 安装 SDK

npm install express-openid-connect dotenv

2. 配置环境变量

使用 Auth0 CLI 自动化设置可参考 Setup Guide。手动设置时创建 .env:

SECRET=<openssl-rand-hex-32>
BASE_URL=http://localhost:3000
CLIENT_ID=your-client-id
CLIENT_SECRET=your-client-secret
ISSUER_BASE_URL=https://your-tenant.auth0.com
AUDIENCE=https://your-api-identifier  # only required if calling external APIs (Step 3a)

生成密钥:openssl rand -hex 32

3. 配置认证中间件

在 app.js 或 index.js 中:

require('dotenv').config();
const express = require('express');
const { auth, requiresAuth } = require('express-openid-connect');

const app = express();

// Configure Auth0 middleware
app.use(auth({
  authRequired: false,  // Don't require auth for all routes
  auth0Logout: true,    // Enable logout endpoint
  secret: process.env.SECRET,
  baseURL: process.env.BASE_URL,
  clientID: process.env.CLIENT_ID,
  issuerBaseURL: process.env.ISSUER_BASE_URL,
  clientSecret: process.env.CLIENT_SECRET
}));

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

这会自动创建 /login、/logout、/callback 端点。

3a. 调用外部 API 时的中间件配置

需要为外部 API 获取访问令牌时,audience 必须放在 authorizationParams 内,放在顶层会被静默忽略且不会签发访问令牌。

// SDK auto-loads SECRET, BASE_URL, CLIENT_ID, ISSUER_BASE_URL, CLIENT_SECRET from env vars
app.use(auth({
  authRequired: false,
  auth0Logout: true,
  authorizationParams: {            // ← required for access tokens
    response_type: 'code',          // ← required: authorization code flow
    audience: process.env.AUDIENCE, // ← API identifier (never top-level)
    scope: 'openid profile email'
  }
}));

在路由中访问令牌:

app.get('/api-call', requiresAuth(), async (req, res) => {
  const { access_token } = req.oidc.accessToken; // object, not a string
  const response = await fetch('https://your-api.com/data', {
    headers: { Authorization: `Bearer ${access_token}` }
  });
  res.json(await response.json());
});

4. 添加路由

// Public route
app.get('/', (req, res) => {
  res.send(req.oidc.isAuthenticated() ? 'Logged in' : 'Logged out');
});

// Protected route
app.get('/profile', requiresAuth(), (req, res) => {
  res.send(`
    <h1>Profile</h1>
    <p>Name: ${req.oidc.user.name}</p>
    <p>Email: ${req.oidc.user.email}</p>
    <pre>${JSON.stringify(req.oidc.user, null, 2)}</pre>
    <a href="/logout">Logout</a>
  `);
});

5. 测试认证

启动服务器:node app.js,访问 http://localhost:3000 测试登录流程。

详细文档

  • Setup Guide:自动化设置脚本、环境配置、Auth0 CLI 使用
  • Integration Guide:受保护路由、会话、API 集成、错误处理
  • API Reference:完整的中间件 API、配置选项、请求属性

常见错误

  • 忘记在 Auth0 Dashboard 添加回调 URL:将 /callback 路径加入 Allowed Callback URLs(如 http://localhost:3000/callback)
  • SECRET 缺失或过弱:用 openssl rand -hex 32 生成并存入 .env 的 SECRET
  • 全局设置 authRequired: true:应设为 false,并在特定路由使用 requiresAuth() 中间件
  • 在 Auth0 中将应用创建为 SPA 类型:服务端认证必须为 Regular Web Application 类型
  • 会话密钥暴露在代码中:始终使用环境变量,切勿硬编码密钥
  • 生产环境 baseURL 错误:将 BASE_URL 更新为生产域名
  • 未处理登出 returnTo:在 Auth0 Dashboard 的 Allowed Logout URLs 中添加域名
  • audience 作为顶层配置键:将 audience 移入 authorizationParams,并配合 response_type: 'code' 与 scope;顶层 audience 会被静默忽略,不签发访问令牌
  • 将 req.oidc.accessToken 当作字符串使用:它是对象,需用 const { access_token } = req.oidc.accessToken 解构

相关 Skills

auth0-quickstart(基础 Auth0 设置)、auth0-migration(从其他认证提供商迁移)、auth0-mfa(添加多因素认证)、auth0-cli(从终端管理 Auth0 资源)

快速参考

中间件选项:authRequired(是否为所有路由要求认证,默认 false)、auth0Logout(是否启用 /logout 端点,默认 false)、secret(会话密钥,必需)、baseURL(应用 URL,必需)、clientID(Auth0 客户端 ID,必需)、issuerBaseURL(Auth0 租户 URL,必需)。

请求属性:req.oidc.isAuthenticated()(检查用户是否登录)、req.oidc.user(用户资料对象)、req.oidc.accessToken(访问令牌对象 { access_token, token_type, expires_in };expires_in 为剩余秒数;用 const { access_token } = req.oidc.accessToken 解构;还暴露 isExpired() 与 refresh() 方法;仅在配置了带 audience 与 response_type: 'code' 的 authorizationParams 时才有值)、req.oidc.idToken(ID 令牌)、req.oidc.refreshToken(刷新令牌)。

常见用例:受保护路由 → 使用 requiresAuth() 中间件;检查认证状态 → req.oidc.isAuthenticated();获取用户信息 → req.oidc.user;调用 API → 参考 Integration Guide。

参考

Express OpenID Connect 文档、Auth0 Express Quickstart、SDK GitHub 仓库。