掘金 后端 ( ) • 2024-03-18 00:10

yma16-logo

⭐背景

大家好,我是yma16,本文分享 node_koa后端——初始化配置jwt和swagger的koa框架。

面向对象:前端初学者、前端转后端的同学

koa简介

Koa 是一个基于 Node.js 平台的下一代 web 开发框架,它采用了 ES6 的特性,基于 async/await 实现异步流程控制。在 Koa 中,路由是指将请求的 URL 路径(或者 URL + 请求方法)映射到具体的处理函数上的过程,这个过程就是路由。

Koa 提供了一个叫做 koa-router 的中间件,用于方便地处理路由。koa-router 的主要功能包括以下几个方面:

路由配置:koa-router 支持通过 put、post、get、delete 等方法定义路由,同时支持多个中间件函数。

路径参数匹配:koa-router 支持在路由路径中定义参数,方便地获取类似 /users/:id 这样的 URL 中的参数。

嵌套路由:koa-router 支持将路由进行嵌套,方便地组织路由,避免重复代码。

路由前缀:koa-router 支持在路由路径中添加前缀,方便地分组路由。

jwt简介

JWT (JSON Web Token)是一种基于 Token 的认证授权机制。

⭐上手搭建项目

💖npm init 初始化一个仓库

# npm init

image.png

安装 koa、koa2-cors、koa-jwt、swagger-jsdoc 关键依赖是koa-hwt

# npm install koa
# npm install koa-bodyparser
# npm install koa2-cors
# npm install koa-jwt
# npm install koa-router
# npm install koa2-swagger-ui swagger-jsdoc

💖封装路由文件自动读取

创建routes目录结构如下

-router
    —routes
        ——index.js
    —swagger
        ——index.js
        ——swagger.json
    ——index.js

router/index.js

const fs = require('fs')
const path = require('path')
// swagger
const Router = require('koa-router');
const swaggerUI = require('koa2-swagger-ui').koaSwagger;
const swaggerSpec = require('./swagger/index');


// 路由
const router = new Router();


module.exports = app => {
    // 读取当前路径下 遍历 routes目录所有文件
    fs.readdirSync(path.join(__dirname, './routes')).forEach(file => {
        const singleRouter = require(`./routes/${file}`);
        // 虚拟路由
        router.use('/api', singleRouter.routes(), singleRouter.allowedMethods());
    })

    //加载文档
    router.get(
        '/swagger',
        swaggerUI({
            routePrefix: false,
            swaggerOptions: {
                spec: swaggerSpec,
            },
        })
    );
    // app 运行 加载虚拟路由
    app.use(router.routes()).use(router.allowedMethods())
}

router/swagger/index.js

const swaggerJSDoc = require('swagger-jsdoc');
const path=require('path');
const fs=require('fs');
const options = {
    definition: {
        openapi: '3.0.0',
        info: {
            title: 'koa 项目 swagger 文档',
            version: '1.0.0',
            description: 'koa项目',
        },
        host: 'localhost:3000/swagger',// 想着改这里,如果不修改,那么接口文档访问地址为:localhost:8000/swagger
        basePath: '/' // Base path (optional)
    },
    // 文档api
    apis: [path.join(__dirname, '../routes/*.js')],
};

const swaggerSpec = swaggerJSDoc(options);

// 写入json
fs.writeFileSync(path.join(__dirname, 'swagger.json'), JSON.stringify(swaggerSpec, null, 2));

module.exports = swaggerSpec;

router\routes\index.js

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

/**
 * @swagger
 * tags:
 *   name: IndexConfig
 *   description: IndexConfig
 */

/**
 * @swagger
 * components:
 *   schemas:
 *     IndexConfig:
 *       type: object
 *       properties:
 *         code:
 *           type: integer
 *           description: network status.
 *         msg:
 *           type: string
 *           description: des
 */

/**
 * @swagger
 * /:
 *   get:
 *     summary: return msg
 *     tags: [IndexConfig]
 *     responses:
 *       200:
 *         description: A list of IndexConfig.
 *         content:
 *           application/json:
 *             schema:
 *               type: Object
 *               items:
 *                 $ref: '#/components/schemas/IndexConfig'
 */
router.get('/', async (ctx) => {
    ctx.body = [{ code: 200, msg: 'koa server'}];
});

module.exports = router;

💖主入口index.js

入口文件配置

const Koa = require('koa');
// jwt
const jwt = require('koa-jwt');

const { koaBody } = require('koa-body');


// 中间件
const cors = require('koa2-cors');

// 引入路由
const routing = require('./router')

const app = new Koa();

// 文件上传
app.use(koaBody({
    multipart: true
}))

// 中间件
app.use(
    cors({
        // origin: function(ctx) { //设置允许来自指定域名请求
        //     // if (ctx.url === '/test') {
        //     //     return '*'; // 允许来自所有域名请求
        //     // }
        //     // return 'http://localhost:8080'; //只允许http://localhost:8080这个域名的请求
        //     return '*'; // 允许来自所有域名请求
        // },
        origin: '*',
        maxAge: 5, //指定本次预检请求的有效期,单位为秒。
        credentials: true, //是否允许发送Cookie
        allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], //设置所允许的HTTP请求方法'
        allowHeaders: ['Content-Type', 'Authorization', 'Accept'], //设置服务器支持的所有头信息字段
        // exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'] //设置获取其他自定义字段
    })
);

// Middleware below this line is only reached if JWT token is valid
// 错误处理
app.use((ctx, next) => {
    return next().catch((err) => {
        if (err.status === 401) {
            ctx.status = 401;
            console.log('401', ctx)
            ctx.body = 'Protected resource, use Authorization header to get access\n';
        } else {
            throw err;
        }
    })
});





// 注意:放在路由前面
app.use(jwt({
    secret: 'yma16-app'
}).unless({ // 配置白名单 api 注册 获取 token 获取验证码
    path: [/\/swagger/]
}))

// 使用路由
routing(app)



const PORT = 3333;
app.listen(PORT, () => {
    console.log(`Server is running at http://localhost:${PORT}/swagger`);
});

💖node index.js运行查看效果

node index.js

运行成功!

node index 访问swagger文档http://localhost:3333/swagger

swagger doc jwt校验访问的api 返回 Protected resource, use Authorization header to get access

image.png

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出! earth

👍 点赞,是我创作的动力!

⭐️ 收藏,是我努力的方向!

✏️ 评论,是我进步的财富!

💖 最后,感谢你的阅读!