1

我正在使用 openApi 3.0 规范、koa2-swagger-ui 和 swagger-jsdoc。我正在尝试获取 swagger ui 上的 Authorize 按钮以允许我输入 JWT 令牌,以便我的请求将被授权。

我按照 OpenApi 3.0 文档在 securitySchemes 中设置了 bearerAuth,并且还使用了安全性使其成为全局性的。所有这些都是在我的 swagger-config.yaml 中实现的。

我想要的是能够在 swagger ui 上单击授权并可以选择输入 JWT。目前,当我单击授权时,该框为空。 空授权 请求响应 401 swagger ui

Swagger.json

    {
  "openapi": "3.0.0",
  "info": {
    "title": "LMS API Specification",
    "version": "1.0.0",
    "description": "Open documentation for LMS API"
  },
  "host": "localhost:8091",
  "basePath": "/",
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/instructor/me": {
      "get": {
        "tags": [
          "Instructor"
        ],
        "description": "Finds all classes and their status for the current user",
        "responses": {
          "200": {
            "description": "You have successfully found all classes and their status for the current user"
          }
        }
      }
    }
  },
  "tags": []
}

招摇配置.yaml

openapi: 3.0.0
info:
  title: LMS API Specification
  version: 1.0.0
  description: Open documentation for LMS API
host: localhost:8091
basePath: /
apis: ['api/v1/instructor/index.js']
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
security:
  - bearerAuth: []

应用程序.js

import Koa from 'koa'
import cors from 'koa-cors'
import serveStatic from 'koa-static'
// import websockify from 'koa-websocket'

import Logger from './lib/Logger'
import authInit from './auth'

import index from './routes/index'
import auth from './routes/auth'
import launch from './routes/launch'
import lesson from './routes/lesson'
import v1 from './api/v1'
import Router from 'koa-router'

export default async port => {
  const koaSwagger = require('koa2-swagger-ui');
  // const app = websockify(new Koa
  const app = new Koa()
  const swaggerJSDoc = require('swagger-jsdoc');
  var router = new Router()
  await authInit(app)

  // Definitions for the swagger docs
  const swaggerDefinition = {
    info: {
      // API informations (required)
      title: 'LMS API Specification', // Title (required)
      version: '1.0.0', // Version (required)
      description: 'OpenAPI documentation for LMS', // Description (optional)
    },
    host: `localhost:8091/api/v1`, // Host (optional)
    basePath: '/', // Base path (optional)
  };
  const options = {
    // Import swaggerDefinitions
    swaggerDefinition,
    // Path to the API docs
    // Note that this path is relative to the current directory from which the Node.js is ran, not the application itself.
    apis: ['api/v1/instructor/index.js'],
  };
  // Initialize swagger-jsdoc -> returns validated swagger spec in json format
  const swaggerSpec = swaggerJSDoc(options);
  router.get('/swagger.json', async (ctx, next) => {

    ctx.set('Content-Type', 'application/json')
    ctx.body = (swaggerSpec);
    return
  });
  app.use(
    koaSwagger({
      swaggerOptions: {
        url: 'http://localhost:8091/swagger.json', // example path to json

      },
      hideTopbar: true,
      routePrefix: '/docs', // route where the view is returned
    }),
  );

  Logger.info(`Running in ${process.env.NODE_ENV} environment`)

  app
    .use(cors())
    .use(serveStatic(__dirname + '/assets'))
    .use(index.routes())
    .use(auth.routes())
    .use(launch.routes())
    .use(lesson.routes())
    .use(v1.routes())
    .use(router.routes())

  return app.listen(port, () => {
    Logger.info(`> Ready on port ${port}`)
  })
}
4

2 回答 2

4

我得到这个最终工作的方法是更新我的 app.js 文件和我的 swagger-config.yaml 文件看起来像这样......

app.js

import Koa from 'koa'
import cors from 'koa-cors'
import serveStatic from 'koa-static'
// import websockify from 'koa-websocket'

import Logger from './lib/Logger'
import authInit from './auth'

import index from './routes/index'
import auth from './routes/auth'
import launch from './routes/launch'
import lesson from './routes/lesson'
import v1 from './api/v1'
import Router from 'koa-router'

export default async port => {
  const koaSwagger = require('koa2-swagger-ui');
  // const app = websockify(new Koa
  const app = new Koa()
  const swaggerJSDoc = require('swagger-jsdoc');
  var router = new Router()
  await authInit(app)

  // Definitions for the swagger docs
  const swaggerDefinition = {
    openapi: '3.0.1',
    info: {
      // API informations (required)
      title: 'LMS API Specification', // Title (required)
      version: '1.0.0', // Version (required)
      description: 'OpenAPI documentation for LMS', // Description (optional)
    },
    servers: [{url: 'http://localhost:8091/'}],
    components: {
      securitySchemes: {
        bearerAuth: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'JWT',
        }
      }
    },
    security: [{
      bearerAuth: []
    }]
  };
  const options = {
    // Import swaggerDefinitions
    swaggerDefinition,
    // Path to the API docs
    // Note that this path is relative to the current directory from which the Node.js is ran, not the application itself.
    apis: ['api/v1/instructor/index.js'],
  };
  // Initialize swagger-jsdoc -> returns validated swagger spec in json format
  const swaggerSpec = swaggerJSDoc(options);
  router.get('/swagger.json', async (ctx, next) => {

    ctx.set('Content-Type', 'application/json')
    ctx.body = (swaggerSpec);
    return
  });
  app.use(
    koaSwagger({
      swaggerOptions: {
        url: 'http://localhost:8091/swagger.json', // example path to json
      },
      hideTopbar: true,
      routePrefix: '/docs', // route where the view is returned
    }),
  );

  Logger.info(`Running in ${process.env.NODE_ENV} environment`)

  app
    .use(cors())
    .use(serveStatic(__dirname + '/assets'))
    .use(index.routes())
    .use(auth.routes())
    .use(launch.routes())
    .use(lesson.routes())
    .use(v1.routes())
    .use(router.routes())

  return app.listen(port, () => {
    Logger.info(`> Ready on port ${port}`)
  })
}

招摇配置.yaml

openapi: 3.0.1
info:
  title: LMS API Specification
  version: 1.0.0
  description: Open documentation for LMS API
servers:
- url: http://localhost:8091/
apis: ['api/v1/instructor/index.js']
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
security:
  - bearerAuth: []

基本上我在 swaggerDefinition 中添加了 openapi: 3.0.1。

于 2019-06-28T18:08:39.373 回答
1

我在 Koa 中使用swagger - jsdoc

这是带有JWT身份验证的工作干净代码的完整示例。

文件夹和文件结构

==> app.js
==> routes/users.route.js
==> middlewares/auth.middleware.js
==> swagger/swaggerOptions.json

应用程序.js

const koa = require('koa');
const koaRouter = require('koa-router');
const cors = require('@koa/cors');
const koaBody = require('koa-bodyparser');
const koaSend = require('koa-send');
const serve = require('koa-static');
const swaggerJsdoc = require('swagger-jsdoc');
const koaSwagger = require('koa2-swagger-ui').koaSwagger;
const app = new koa();
const router = new koaRouter();

const authMiddleware = require('./middlewares/auth.middleware');
const users = require('./routes/users.route');

const swagger = swaggerJsdoc(require('./swagger/swaggerOptions.json'));

router.get('/swagger.json', ctx => ctx.body = swagger);
router.get('/api-docs', koaSwagger({ routePrefix: false, swaggerOptions: { spec: swagger } }));

router.use('/users', users.routes(), users.allowedMethods());

app 
  .use(serve('.'))
  .use(koaBody({ jsonLimit: '100mb', formLimit: '100mb', textLimit: '100mb' }))
  .use(cors())
  .use(router.routes())
  .use(router.allowedMethods())

app.listen(3000);

users.router.js

const koaRouter = require('koa-router');
const router = new koaRouter();

/**
 * @swagger
 *  tags:
 *   name: Users
 *   description: API to manage action types.
 */

/**
*  @swagger
*   components:
*     securitySchemes:
*       AccessToken:      # arbitrary name for the security scheme
*         type: apiKey
*         in: header       # can be "header", "query" or "cookie"
*         name: x-access-token  # name of the header, query parameter or cookie
*/

/**
*  @swagger
*   components:
*     schemas:
*       ArrayResponse:
*         type: object
*         required:
*           - success
*           - message
*         properties:
*           success:
*             type: boolean
*             description: successsful or failed
*           message:
*             type: string
*             description: name can be any string
*           data:
*             type: array
*         example:
*            success: true
*            message: "ok"
*            data: []
*/ 

/**
 * @swagger
 *  /:
 *    get:
 *      summary: it will return list of all users
 *      tags: [Users]
 *      security:
 *        - AccessToken: []
 *      responses:
 *        "200":
 *          description: record found successfully.
 *          content:
 *            application/json:
 *              schema:
 *                $ref: '#/components/schemas/ArrayResponse'
 *
 */

router.get('/', authMiddleware(), async (ctx, next) => {  
    ctx.status = 200;
    ctx.body = {
        success: true,
        message: "all users",
        data: [1, 2, 3, 4, 5]
    }
});

module.exports = router;

swaggerOptions.json

{
    "definition": {
        "openapi": "3.0.0",
        "info": {
            "title": "admin Swagger Doc",
            "version": "1.0.0",
            "description": "Complete api information",
            "contact": {
                "name": "admin",
                "url": "http://localhost:3000",
                "email": "admin@admin.com"
            }
        },
        "servers": [
            {
                "url": "http://localhost:3000",
                "description": "Local Server"
            },
            {
                "url": "http:/0.0.0.0:3001",
                "description": "Development Server"
            }
        ]
    },
    "schemes": [
        "https",
        "http"
    ],
    "apis": [
        "./routes/*.js"
    ]
}

auth.middleware.js

const jwt = require("jsonwebtoken");
function middleware() {
    return async (ctx, next) => {
        const accessToken = ctx.headers["x-access-token"];
        if (!accessToken) {

            log("token not found");
            ctx.throw("x-access-token header is required.");
        } 

        try {
            const decoded = jwt.verify(accessToken, "SECRET_KEY");
            ctx.state.authUser = decoded;
        } catch (error) {
            log("invalid x-access-token.", error.message);
            ctx.throw("x-access-token invalid.");
        }
        await next();
    }
}
module.exports = middleware;

在此处输入图像描述

于 2021-10-03T08:57:29.693 回答