forked from yoone/API
1
0
Fork 0
API/src/middleware/auth.middleware.ts

104 lines
2.7 KiB
TypeScript

// 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<Context, NextFunction> {
@Inject()
jwtService: JwtService; // 注入 JwtService 实例
@Inject()
deviceWhitelistService: DeviceWhitelistService;
// 白名单配置
whiteList = [
'/user/login',
'/webhook/woocommerce',
'/logistics/getTrackingNumber',
'/logistics/getListByTrackingId',
'/product/categories/all',
'/product/category/1/attributes',
'/product/category/2/attributes',
'/product/category/3/attributes',
'/product/category/4/attributes',
'/product/list',
'/dict/items',
];
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);
}
}