// src/middleware/auth.middleware.ts import { IMiddleware, Middleware, Inject, NextFunction, httpError, } from '@midwayjs/core'; import { Context } from '@midwayjs/koa'; import { JwtService } from '@midwayjs/jwt'; // 引入 JwtService 类型 import { DeviceWhitelistService } from '../service/deviceWhitelist.service'; @Middleware() export class AuthMiddleware implements IMiddleware { @Inject() jwtService: JwtService; // 注入 JwtService 实例 @Inject() deviceWhitelistService: DeviceWhitelistService; // 白名单配置 whiteList = [ '/user/login', '/webhook/woocommerce', '/logistics/getTrackingNumber', '/logistics/getListByTrackingId', ]; match(ctx: Context) { return !this.isWhiteListed(ctx); } resolve() { return async (ctx: Context, next: NextFunction) => { // 判断下有没有校验信息 if (!ctx.headers['authorization']) { throw new httpError.UnauthorizedError(); } // 从 header 上获取校验信息 const parts = ctx.get('authorization').trim().split(' '); if (parts.length !== 2) { throw new httpError.UnauthorizedError(); } const [scheme, token] = parts; if (!/^Bearer$/i.test(scheme)) { throw new httpError.UnauthorizedError('Invalid Token Scheme'); } try { // 2. 校验 JWT 并解析 payload const decoded: any = await this.jwtService.verify(token); const deviceId: string = decoded.deviceId; if (!deviceId) { throw new httpError.UnauthorizedError('Missing deviceId in token'); } // 3. 校验设备是否在白名单 const isWhite = await this.deviceWhitelistService.isWhitelisted( deviceId ); if (!isWhite) { throw new httpError.UnauthorizedError('Device not authorized'); } } catch (error) { throw new httpError.UnauthorizedError('Invalid or expired token'); } if (/^Bearer$/i.test(scheme)) { try { //jwt.verify方法验证token是否有效 await this.jwtService.verify(token, { complete: true, }); } catch (error) { throw new httpError.UnauthorizedError(); } await next(); } }; } static getName(): string { return 'authMiddleware'; } static getPriority(): number { return 0; } isWhiteListed(ctx: Context): boolean { return this.whiteList.includes(ctx.path); } }