logo
0
0
WeChat Login

@cicctencent/midwayjs-base

npm version License: MIT

MidwayJS 企业级基础组件 - 集成公司常用基础服务能力,快速构建后端应用。

简介

@cicctencent/midwayjs-base 是一个基于 MidwayJS 3.x 框架的企业级基础组件,封装了公司内部常用的基础服务能力,包括认证授权、文件存储、API 网关、会话管理等功能,帮助开发者快速搭建稳定可靠的后端服务。

功能特性

🔐 认证授权

  • JWT Token 认证(支持 HS256 算法)
  • 单点登录 (SSO) 集成
  • 接口权限守卫(AuthGuard)
  • 管理员账号验证

📁 文件存储

  • 腾讯云 COS 文件上传/下载
  • 文件访问 URL 生成(带临时签名)
  • 多存储桶配置支持
  • 支持流式上传

🔌 API 网关

  • 统一 API 响应格式 { ret, msg, data }
  • 请求参数校验
  • IP 白名单控制
  • API Token 验证(带时间戳防重放)

💾 会话管理

  • 分布式会话存储(基于 Midway Cache)
  • 会话超时配置
  • 自定义会话服务接口(ISessionService)

🛡️ 安全防护

  • 请求检测中间件(DetectMiddleware)
  • 统一异常过滤器
  • 404 处理
  • XSS 防护

📝 日志系统

  • 结构化日志输出
  • 远程日志上报
  • 请求 ID 追踪
  • 自动注入用户信息

目录结构

src/
├── config/                    # 配置文件
│   ├── config.default.ts      # 默认配置
│   └── env.ts                 # 环境变量加载
├── filter/                    # 异常过滤器
│   ├── default.filter.ts      # 默认异常处理
│   └── notfound.filter.ts     # 404 处理
├── guard/                     # 守卫器
│   ├── api.ts                 # API Token 验证守卫
│   └── auth.ts                # 登录态验证守卫
├── lib/                       # 工具库
│   ├── decorator.ts           # 自定义装饰器
│   ├── jwt.ts                 # JWT 工具函数
│   ├── request.ts             # 请求工具
│   └── utils.ts               # 通用工具函数
├── middleware/                # 中间件
│   ├── apiResultFormatter.ts  # API 响应格式化
│   ├── detect.middleware.ts   # 客户端检测
│   └── requestInit.ts         # 请求初始化
├── service/                   # 服务类
│   ├── session.service.ts     # 会话服务
│   └── tencent.service.ts     # 腾讯云服务
├── types/                     # 类型定义
│   ├── base.controller.ts     # 控制器基类
│   ├── base.model.service.ts  # 模型服务基类
│   ├── base.service.ts        # 服务基类
│   └── session.service.interface.ts  # 会话服务接口
├── configuration.ts           # 组件配置
└── index.ts                   # 入口文件

快速开始

安装

npm install @cicctencent/midwayjs-base

基础配置

src/configuration.ts 中引入组件:

import { Configuration } from '@midwayjs/core';
import * as base from '@cicctencent/midwayjs-base';

@Configuration({
  imports: [
    base  // 引入基础组件
  ],
  importConfigs: [
    // 你的业务配置
  ]
})
export class MainConfiguration {
  // 配置
}

环境变量配置

创建 .env 文件:

# 应用配置
APP_ID=1001
SERVICE_NAME=your-service-name

# API 配置
API_KEY=your-api-key

# SSO 配置
SSO_URL=https://sso.example.com

# 基础服务地址
BASE_SERVER_URL=https://base-service.example.com

# 腾讯云配置
TENCENT_CREDENTIAL_SECRETID=your-secret-id
TENCENT_CREDENTIAL_SECRETKEY=your-secret-key

# 会话配置
SESSION_TIMEOUT=1200000

# 日志配置
LOG_LEVEL=info
REMOTE_LOGGER_URL=https://log.example.com/api/report

核心功能使用

1. 基础服务类 (BaseService)

继承 BaseService 获取基础能力:

import { Provide } from '@midwayjs/core';
import { BaseService } from '@cicctencent/midwayjs-base';
import { GetUserInfoReq, GetUserInfoRes } from '@fefeding/common/dist/models/user/request';

@Provide()
export class UserService extends BaseService {
  /**
   * 获取用户信息
   * @param userId 用户ID
   */
  async getUserInfo(userId: number) {
    // 检查是否为管理员
    const isManager = await this.checkManager();
    
    // 方式1:使用请求对象(推荐)
    const req = new GetUserInfoReq();
    req.userId = userId;
    const result = await this.requestBaseApi<GetUserInfoRes>(req);
    
    // 方式2:使用 URL 路径
    // const result = await this.requestBaseApi('/api/user/getInfo', {
    //   data: { userId }
    // });
    
    return result?.data || null;
  }
}

BaseService 提供的能力:

  • checkManager(account?) - 检查是否为管理员账号
  • requestBaseApi(req, option) - 请求基础服务(返回 data)
  • requestBaseServer(req, option) - 请求基础服务(返回完整响应)

2. 会话服务类 (SessionService)

继承 ISessionService 实现自定义会话管理:

import { Provide, Scope, ScopeEnum, Config, Inject } from '@midwayjs/core';
import { ISessionService, TencentService } from '@cicctencent/midwayjs-base';
import { Session, GetLoginSessionReq } from '@fefeding/common/dist/models/account/session';

@Provide('session:service')
@Scope(ScopeEnum.Request, { allowDowngrade: true })
export class SessionService extends ISessionService { 
    @Config('loginOption')
    loginOption: any;

    @Inject()
    tencentService: TencentService;

    /**
     * 根据Token获取会话信息
     * @param id 会话Token
     */
    async getLoginSession(id: string): Promise<Session | null> {
        const req = new GetLoginSessionReq();
        req.id = id;
        const res = await this.requestBaseApi(req);
        return res?.data || null;
    }

    /**
     * 用户登出
     * @param id 会话Token
     */
    async logout(id: string): Promise<any> {
        this.ctx.currentSession = null;
        return { success: true };
    }

    /**
     * 通过临时授权码登录
     * @param code 授权码
     */
    async loginByCode(code: string): Promise<Session | null> {
        const res = await this.requestBaseApi('/api/session/loginByAuthCode', {
            data: { code }
        });
        return res?.data || null;
    }
}

3. 控制器基类 (BaseController)

import { Controller, Get, Post } from '@midwayjs/core';
import { BaseController } from '@cicctencent/midwayjs-base';

@Controller('/api/user')
export class UserController extends BaseController {
  
  @Get('/info')
  async getUserInfo() {
    // 获取当前会话信息
    const session = this.ctx.currentSession;
    
    return {
      userId: session.userId,
      account: session.account
    };
  }
}

4. 装饰器使用

import { Controller, Get, Post } from '@midwayjs/core';
import { checkLogin, checkApiToken, checkIP } from '@cicctencent/midwayjs-base';

@Controller('/api')
export class ApiController {
  
  @Get('/public')
  async publicApi() {
    // 公开接口,无需认证
    return { message: 'public' };
  }

  @Get('/user/info')
  @checkLogin()  // 需要登录态
  async getUserInfo() {
    return this.ctx.currentSession;
  }

  @Post('/admin/action')
  @checkLogin()
  @checkIP()     // 检查IP白名单
  async adminAction() {
    // 仅允许白名单IP访问
    return { success: true };
  }

  @Post('/internal/sync')
  @checkApiToken()  // 验证API Token
  async syncData() {
    // 需要携带有效的 api_token 和 timestamp
    return { success: true };
  }
}

5. 腾讯云 COS 服务

import { Provide, Inject } from '@midwayjs/core';
import { TencentService } from '@cicctencent/midwayjs-base';

@Provide()
export class FileService {
  
  @Inject()
  tencentService: TencentService;
  
  /**
   * 上传文件到 COS
   * @param filePath 本地文件路径
   * @param key COS对象键
   */
  async uploadFile(filePath: string, key: string) {
    // 上传文件
    const result = await this.tencentService.uploadCosFile(key, filePath);
    
    // 获取带签名的访问URL
    const url = await this.tencentService.getCosFileUrl(key);
    
    return {
      ...result,
      url
    };
  }

  /**
   * 上传数据到 COS
   * @param key COS对象键
   * @param data 数据内容(字符串、Buffer、ReadStream等)
   */
  async uploadData(key: string, data: any) {
    return await this.tencentService.uploadCosData(key, data);
  }

  /**
   * 获取文件内容
   * @param key COS对象键
   */
  async getFile(key: string) {
    return await this.tencentService.getFile(key);
  }
}

6. JWT 工具

import { jwt } from '@cicctencent/midwayjs-base';

// 生成 JWT Token
const token = jwt.encodeJWT(
  { userId: 123, loginId: 'user001' },
  'your-secret-key',
  { expiresIn: '7d' }  // 可选:过期时间
);

// 解码 JWT Token
const payload = jwt.decodeJWT(token, 'your-secret-key');
if (payload) {
  console.log('用户ID:', payload.userId);
}

7. 通用工具函数

import { utils } from '@cicctencent/midwayjs-base';

// 检查URL是否属于指定域名
const isValid = utils.checkUrlHost('https://example.com/path', 'example.com');

// 获取/设置认证Token
const token = utils.getAuthToken(ctx);
utils.setAuthToken(ctx, 'new-token');

// 渲染模板
await utils.getDefaultTemplate(ctx, 'index.html', { title: '首页' });

配置说明

完整配置项

// config/config.default.ts
export default {
  // Cookie 签名密钥
  keys: 'your-app-keys',
  
  // Cookie 配置
  cookies: {
    secret: '',  // 空字符串表示关闭加密
  },

  // 视图配置(Nunjucks)
  view: {
    defaultViewEngine: 'nunjucks',
    rootDir: {
      default: path.join(appInfo.webDist, 'view/'),
    },
    mapping: {
      '.html': 'nunjucks',
    },
  },

  // 文件上传配置
  upload: {
    mode: 'file',
    fileSize: '10mb',
    whitelist: ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx'],
  },

  // 静态文件服务
  staticFile: {
    dirs: {
      default: {
        dir: appInfo.webPublic,
      },
    },
  },

  // API 配置
  apiOption: {
    key: 'your-api-key',           // API Token 密钥
    reg: /^\/([^/]+\/)?api\//i,     // API 路径匹配正则
    ignore: ['/'],                  // 忽略路径
  },

  // IP 白名单
  ipOption: {
    whiteList: ['127.0.0.1', '::1', '0.0.0.0'],
  },

  // 基础服务配置
  baseService: {
    manager: ['admin'],             // 管理员账号列表
    appId: 1001,                    // 应用ID
    url: 'https://base-service.example.com',
  },

  // 会话配置
  session: {
    timeout: 1200000,               // 过期时间(毫秒),默认20分钟
    secretKey: 'your-session-secret',
  },

  // 登录态校验配置
  auth: {
    ignores: [/\/api\/test\//i],   // 忽略登录态校验的路径
  },

  // SSO 配置
  sso: {
    baseUrl: 'https://sso.example.com',
    appId: 1001,
  },

  // 腾讯云凭证
  tencentCredential: {
    secretId: 'your-secret-id',
    secretKey: 'your-secret-key',
  },

  // 请求体解析配置
  bodyParser: {
    formLimit: '30mb',
    jsonLimit: '30mb',
  },

  // 缓存配置
  cacheManager: {
    clients: {
      default: {
        store: 'memory',
        options: {
          max: 10000,    // 最大缓存key数量
          ttl: 600000,   // 过期时间(毫秒)
        },
      },
    },
  },

  // 日志配置
  logger: {
    level: 'info',
    consoleLevel: 'info',
    remoteUrl: '',  // 远程日志上报地址
  },
};

中间件说明

内置中间件执行顺序

请求 → RequestInitMiddleware → DetectMiddleware → ApiResultFormatterMiddleware → Guard → Controller
  1. RequestInitMiddleware: 请求初始化

    • 生成请求 ID
    • 初始化日志器
    • 记录请求耗时
  2. DetectMiddleware: 客户端检测

    • 检测移动端/PC端
    • 检测微信/QQ环境
    • 获取客户端IP
  3. ApiResultFormatterMiddleware: API 响应格式化

    • 统一响应格式 { ret, msg, data }
    • 异常处理

守卫器

  1. ApiGuard: API 接口守卫

    • @checkApiToken() - 验证 API Token
    • @checkIP() - IP 白名单检查
  2. AuthGuard: 认证守卫

    • @checkLogin() - 登录态验证
    • 支持 SSO 回调处理
    • 支持 JWT Token 认证

开发指南

本地开发

# 安装依赖
npm install

# 构建
npm run build

# 测试
npm test

# 代码检查
npm run lint
npm run lint:fix

发布

# 构建
npm run build

# 发布
npm publish --access public

依赖说明

核心依赖

  • @midwayjs/core - MidwayJS 核心框架
  • @midwayjs/koa - Koa 适配器
  • @fefeding/common - 公共模型和工具库

功能依赖

  • jsonwebtoken - JWT 处理
  • axios - HTTP 客户端
  • typeorm - ORM 支持
  • dayjs - 日期处理

版本历史

v1.0.38 (当前版本)

  • 优化请求初始化中间件
  • 增强错误处理机制

v1.0.35+

  • 基础功能稳定版本
  • 完整的认证授权体系
  • 腾讯云 COS 集成

技术支持

如有问题或建议,请联系开发团队。

许可证

MIT License

About

midwayjs的基础框架,包含一些通用的服务

Language
TypeScript99.3%
JavaScript0.5%
Smarty0.3%