APISIX Dashboard实战:从零配置JWT认证网关(含Node.js后端对接)

APISIX Dashboard实战:从零构建JWT认证网关与Node.js后端深度集成

引言:为什么选择APISIX作为API网关?

在现代微服务架构中,API网关扮演着流量调度和安全防护的双重角色。APISIX作为云原生API网关的佼佼者,凭借其动态路由、插件热加载和Dashboard可视化配置等特性,成为开发者构建安全API服务的首选方案。特别是当我们需要为Node.js后端服务添加JWT认证层时,APISIX提供了一套完整的解决方案。

本教程将带您从零开始,完成以下关键任务:

  • 在APISIX Dashboard中配置JWT认证路由
  • 创建安全的消费者密钥体系
  • 搭建Node.js示例服务并实现JWT验证集成
  • 解决跨服务调试中的常见陷阱

无论您是刚接触API网关概念的开发者,还是需要快速落地企业级认证方案的DevOps工程师,这套闭环流程都能为您提供可直接复用的实践参考。

1. 环境准备与APISIX基础配置

1.1 安装APISIX及Dashboard

推荐使用Docker快速搭建开发环境:

# 创建APISIX网络 docker network create apisix # 启动etcd(APISIX的配置存储) docker run -d --name etcd \ --network apisix \ -p 2379:2379 \ -e ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 \ -e ETCD_ADVERTISE_CLIENT_URLS=http://0.0.0.0:2379 \ bitnami/etcd:latest # 启动APISIX docker run -d --name apisix \ --network apisix \ -p 9080:9080 -p 9180:9180 \ -v ./apisix_log:/usr/local/apisix/logs \ apache/apisix:latest # 启动Dashboard docker run -d --name apisix-dashboard \ --network apisix \ -p 9000:9000 \ -v ./dashboard_conf:/usr/local/apisix-dashboard/conf \ apache/apisix-dashboard:latest

注意:生产环境需要配置持久化存储和更严格的安全策略,此处为开发测试简化配置。

1.2 初始登录与界面概览

访问Dashboard的默认地址:

http://localhost:9000

默认凭证:

  • 用户名:admin
  • 密码:admin

首次登录后建议立即修改密码。Dashboard主界面主要包含以下功能区域:

功能区主要功能
路由管理创建/编辑API路由规则
上游管理后端服务配置
消费者管理JWT等认证配置
插件市场启用/配置各类网关插件
系统监控流量指标与日志查看

2. JWT认证核心配置流程

2.1 创建JWT签名路由

首先需要配置一个用于生成JWT Token的公开接口:

  1. 进入路由管理创建路由
  2. 填写基础信息:
    • 路由名称:jwt-signer
    • 路径:/auth/token
    • 请求方法:GET
  3. 在插件配置中启用public-api插件
  4. 点击"提交"完成创建

此时可以通过CURL验证路由是否生效:

curl -i http://localhost:9080/auth/token

2.2 配置消费者与密钥

消费者(Consumer)代表使用API的客户端,我们需要为其配置JWT认证:

  1. 进入消费者管理创建消费者
  2. 填写基本信息:
    • 用户名:nodejs-client
    • 描述:Node.js后端服务客户端
  3. 在插件配置中添加jwt-auth插件:
    { "algorithm": "HS256", "key": "nodejs-app-key", "secret": "your-strong-secret-here", "exp": 3600 }
    • key:客户端标识,后续用于获取Token
    • secret:签名密钥,建议使用强密码生成器创建
    • exp:Token有效期(秒)

安全提示:实际生产环境中,secret应当通过环境变量注入,而非直接写在配置中。

2.3 获取测试Token

现在可以通过以下方式获取JWT Token:

curl "http://localhost:9080/auth/token?key=nodejs-app-key"

正常响应示例:

{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJub2RlanMtYXBwLWtleSIsImV4cCI6MTY4MDAwMDAwMH0.abc123def456ghi789jkl012mno345pqr678stu901vwx234yz" }

3. Node.js后端服务集成

3.1 搭建基础Express服务

创建项目目录并初始化:

mkdir nodejs-api && cd nodejs-api npm init -y npm install express jsonwebtoken

创建server.js文件:

const express = require('express'); const jwt = require('jsonwebtoken'); const app = express(); const PORT = 3000; // 中间件:验证APISIX传递的JWT const verifyToken = (req, res, next) => { const token = req.headers['x-access-token']; if (!token) return res.status(403).send('Token required'); try { const decoded = jwt.verify(token, 'your-strong-secret-here'); req.user = decoded; next(); } catch (err) { return res.status(401).send('Invalid token'); } }; // 受保护的路由 app.get('/api/protected', verifyToken, (req, res) => { res.json({ message: 'Access granted', user: req.user }); }); app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); });

3.2 配置APISIX上游与保护路由

  1. 在Dashboard中创建上游:

    • 名称:nodejs-backend
    • 节点:127.0.0.1:3000(根据实际服务地址调整)
  2. 创建保护路由:

    • 路径:/api/*
    • 绑定上游:nodejs-backend
    • 启用插件:
      • proxy-rewrite:重写路径(可选)
      • jwt-auth:使用之前配置的消费者认证

关键配置示例:

{ "jwt-auth": { "header": "x-access-token", "query": "token", "cookie": "auth_token" } }

4. 联调测试与故障排查

4.1 完整请求流程测试

  1. 获取Token:

    TOKEN=$(curl -s "http://localhost:9080/auth/token?key=nodejs-app-key" | jq -r '.token')
  2. 访问受保护API:

    curl -H "x-access-token: $TOKEN" http://localhost:9080/api/protected

预期成功响应:

{ "message": "Access granted", "user": { "key": "nodejs-app-key", "exp": 1680000000 } }

4.2 常见问题解决方案

问题1:Token无效或过期

  • 检查消费者配置的secret是否与Node.js服务一致
  • 验证Token有效期设置
  • 使用jwt.io调试Token内容

问题2:跨域请求失败在路由配置中添加CORS插件:

{ "cors": { "allow_origins": "*", "allow_methods": ["GET","POST","PUT","DELETE"], "allow_headers": ["x-access-token"] } }

问题3:上游服务不可达

  • 在APISIX日志中查找错误:
    docker logs apisix
  • 验证上游健康检查配置
  • 检查网络连通性

5. 高级配置与优化建议

5.1 JWT密钥轮换策略

为提高安全性,建议实现密钥轮换:

  1. 创建新消费者配置:

    { "algorithm": "HS256", "key": "nodejs-app-key-v2", "secret": "new-strong-secret", "exp": 3600 }
  2. 在Node.js服务中支持多密钥验证:

    const secrets = { 'nodejs-app-key': 'original-secret', 'nodejs-app-key-v2': 'new-strong-secret' }; const decoded = jwt.verify(token, secrets[req.user.key]);
  3. 逐步迁移客户端到新key

5.2 性能优化配置

参数推荐值说明
jwt_expires_in3600Token有效期(秒)
keepalive_pool50连接池大小
upstream_timeout3000上游响应超时(毫秒)
rate_limit1000/分钟防止滥用

在路由插件中配置:

{ "limit-count": { "count": 1000, "time_window": 60, "key_type": "var", "key": "consumer_name" } }

5.3 监控与日志集成

建议配置:

  1. 启用Prometheus插件监控API指标
  2. 将访问日志推送到ELK或Graylog
  3. 设置JWT认证失败告警

示例Prometheus配置:

plugin_attr: prometheus: export_addr: ip: "0.0.0.0" port: 9091

6. 实际项目中的经验分享

在电商项目中,我们曾遇到JWT Token被盗用的问题。最终通过以下组合方案解决:

  1. 绑定IP白名单:

    { "jwt-auth": { "whitelist": ["192.168.1.0/24"] } }
  2. 添加自定义声明验证:

    // Node.js验证逻辑中添加 if (decoded.client_type !== 'trusted') { throw new Error('Invalid client type'); }
  3. 启用APISIX的anti-replay插件防止重放攻击

另一个实用技巧是在开发环境使用不同的密钥策略。我们通常在开发环境:

  • 设置更长的有效期(如24小时)
  • 使用简化的secret便于调试
  • 禁用部分严格检查

而在生产环境则:

  • 启用双因素认证
  • 实施严格的速率限制
  • 监控异常Token使用模式