查看: 187|回复: 0

Node.js 集成 Swagger 生成 JWT 接口文档

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
Swagger 在 Node.js/Express 项目中的常见落地方式是:swagger-jsdoc 把路由文件里的 JSDoc 注释转成 OpenAPI 规范,swagger-ui-express 把规范渲染成可交互的 API 文档页面。原文以用户管理 API 为例,使用 OpenAPI 3.0.0,扫描路径为 ./src/routes/*.js,文档挂载到 /api-docs,并通过 bearerAuth 声明 JWT 认证。

一、安装依赖
  1. npm install swagger-jsdoc swagger-ui-express
复制代码
其中 swagger-jsdoc 负责把 JSDoc 注释转换为 Swagger/OpenAPI 规范,swagger-ui-express 负责提供 Swagger UI 界面。

二、配置 src/config/swagger.js
核心配置包括 openapi 版本、info 信息、servers、securitySchemes、schemas、tags、security 和 apis 扫描路径。原文在 components.schemas 中还定义了 LoginResponse、UserListResponse、User、CreateUserRequest 等结构,下面保留核心配置结构:
  1. // src/config/swagger.js
  2. const swaggerJsdoc = require('swagger-jsdoc')
  3. const options = {
  4.   definition: {
  5.     openapi: '3.0.0',
  6.     info: {
  7.       title: '用户管理 API 文档',
  8.       version: '1.0.0',
  9.       description: '基于 Express + JWT 的用户管理接口文档',
  10.       contact: { name: 'API Support', email: 'support@example.com' },
  11.       license: { name: 'MIT', url: 'https://opensource.org/licenses/MIT' }
  12.     },
  13.     servers: [
  14.       { url: 'http://localhost:3000/api', description: '开发服务器' },
  15.       { url: 'https://api.example.com/api', description: '生产服务器' }
  16.     ],
  17.     components: {
  18.       securitySchemes: {
  19.         bearerAuth: {
  20.           type: 'http',
  21.           scheme: 'bearer',
  22.           bearerFormat: 'JWT',
  23.           description: '输入 Bearer Token'
  24.         }
  25.       },
  26.       schemas: {
  27.         ApiResponse: {
  28.           type: 'object',
  29.           properties: {
  30.             code: { type: 'integer', description: '状态码:0-成功,其他-失败', example: 0 },
  31.             msg: { type: 'string', description: '响应消息', example: '操作成功' },
  32.             data: { type: 'object', description: '响应数据' }
  33.           }
  34.         },
  35.         LoginRequest: {
  36.           type: 'object',
  37.           required: ['username', 'password'],
  38.           properties: {
  39.             username: { type: 'string', description: '用户名', example: 'admin' },
  40.             password: { type: 'string', description: '密码', example: '123456' }
  41.           }
  42.         }
  43.       }
  44.     },
  45.     security: [{ bearerAuth: [] }],
  46.     tags: [
  47.       { name: '认证', description: '用户认证相关接口' },
  48.       { name: '用户管理', description: '用户管理相关接口' }
  49.     ]
  50.   },
  51.   apis: ['./src/routes/*.js']
  52. }
  53. module.exports = swaggerJsdoc(options)
复制代码

三、在 app.js 中集成 Swagger UI
  1. const express = require('express')
  2. const cors = require('cors')
  3. require('dotenv').config()
  4. const swaggerUi = require('swagger-ui-express')
  5. const swaggerSpec = require('./config/swagger')
  6. const authRoutes = require('./routes/auth')
  7. const userRoutes = require('./routes/user')
  8. const app = express()
  9. const PORT = process.env.PORT || 3000
  10. app.use(cors())
  11. app.use(express.json())
  12. app.use(express.urlencoded({ extended: true }))
  13. app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, {
  14.   explorer: true,
  15.   customCss: '.swagger-ui .topbar { display: none }',
  16.   customSiteTitle: '用户管理 API 文档',
  17.   swaggerOptions: { persistAuthorization: true }
  18. }))
  19. app.get('/api-docs.json', (req, res) => {
  20.   res.setHeader('Content-Type', 'application/json')
  21.   res.send(swaggerSpec)
  22. })
  23. app.use('/api/auth', authRoutes)
  24. app.use('/api/user', userRoutes)
  25. app.listen(PORT, () => {
  26.   console.log(`服务器地址: http://localhost:${PORT}`)
  27.   console.log(`Swagger 文档: http://localhost:${PORT}/api-docs`)
  28. })
复制代码
这里 explorer 用于显示搜索框,customCss 隐藏顶部栏,customSiteTitle 设置页面标题,persistAuthorization 持久化认证信息;/api-docs.json 可导出 Swagger 规范给其他工具使用。

四、在路由中写 JSDoc 注释
认证路由的登录接口可按如下方式声明请求体和响应:
  1. /**
  2. * @swagger
  3. * /auth/login:
  4. *   post:
  5. *     summary: 用户登录
  6. *     description: 使用用户名和密码登录,返回 JWT Token
  7. *     tags: [认证]
  8. *     requestBody:
  9. *       required: true
  10. *       content:
  11. *         application/json:
  12. *           schema:
  13. *             $ref: '#/components/schemas/LoginRequest'
  14. *     responses:
  15. *       200:
  16. *         description: 登录成功
  17. *         content:
  18. *           application/json:
  19. *             schema:
  20. *               $ref: '#/components/schemas/LoginResponse'
  21. *       400:
  22. *         description: 请求参数错误
  23. *       401:
  24. *         description: 用户名或密码错误
  25. *       403:
  26. *         description: 用户已被禁用
  27. */
  28. router.post('/login', async (req, res) => {
  29.   // ... 原有代码
  30. })
复制代码
用户列表接口需要声明 security 和 query 参数,参数含义包括 page 页码、size 每页大小、keyword 关键词搜索、status 状态 0/1、role 角色枚举:
  1. /**
  2. * @swagger
  3. * /user/list:
  4. *   get:
  5. *     summary: 获取用户列表
  6. *     tags: [用户管理]
  7. *     security:
  8. *       - bearerAuth: []
  9. *     parameters:
  10. *       - in: query
  11. *         name: page
  12. *         schema: { type: integer, default: 1 }
  13. *         description: 页码
  14. *       - in: query
  15. *         name: size
  16. *         schema: { type: integer, default: 10 }
  17. *         description: 每页大小
  18. *       - in: query
  19. *         name: keyword
  20. *         schema: { type: string }
  21. *         description: 关键词搜索(用户名或邮箱)
  22. *       - in: query
  23. *         name: status
  24. *         schema: { type: integer, enum: [0, 1] }
  25. *         description: 用户状态:0-禁用,1-启用
  26. *       - in: query
  27. *         name: role
  28. *         schema: { type: string, enum: [admin, manager, user, developer] }
  29. *         description: 用户角色
  30. *     responses:
  31. *       200:
  32. *         description: 获取用户列表成功
  33. *         content:
  34. *           application/json:
  35. *             schema:
  36. *               $ref: '#/components/schemas/UserListResponse'
  37. *       400:
  38. *         description: 请求参数错误
  39. *       401:
  40. *         description: 未登录或 Token 无效
  41. */
  42. router.get('/list', authenticate, (req, res) => {
  43.   // ... 原有代码
  44. })
复制代码

五、访问与调试
启动服务后访问 http://localhost:3000/api-docs。Swagger UI 顶部提供搜索框,左侧按 Tags 分组显示接口,右侧显示选中接口的详细信息。需要 Token 的接口先点击右上角 Authorize,输入 Bearer <你的Token> 并确认。测试接口时展开目标接口,点击 Try it out,填写参数后点击 Execute 查看响应结果。原文还列出的导出方案包括使用 swagger-to-markdown 以及通过 Swagger Editor 导出 Markdown/PDF;常见问题部分列出了 Swagger 页面空白、JSDoc 注释没有被解析、Swagger 中显示不了中文三类现象。

整体上,这种写法的关键是让路由注释、swagger.js 中的 schemas 定义和实际接口实现保持同步;接口路径、参数、JWT 认证声明一旦变化,也要同步修改对应 JSDoc 注释,否则最终渲染出的 API 文档会与实现不一致。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-24 12:39 , Processed in 0.022493 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部