Files
Edu/services/iam/src/app.module.ts
SpecialX a35e759d64 feat(iam): 完整实现 iam 身份认证与权限服务
包含 jwt/jwks/audit/grpc、rbac、cache、redis/kafka 配置等完整实现
2026-07-10 19:09:39 +08:00

86 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
Module,
NestModule,
MiddlewareConsumer,
OnModuleInit,
Logger,
} from "@nestjs/common";
import { APP_GUARD } from "@nestjs/core";
import { IamModule } from "./iam/iam.module.js";
import { HealthModule } from "./shared/health/health.module.js";
import { PermissionGuard } from "./middleware/permission.guard.js";
import { AuthMiddleware } from "./middleware/auth.middleware.js";
import { LifecycleService } from "./shared/lifecycle/lifecycle.service.js";
import { OutboxModule } from "@edu/shared-ts/outbox";
import { getDbInstance } from "./config/database.js";
import {
getKafkaProducer,
connectKafkaProducer,
IAM_KAFKA_TOPICS,
} from "./config/kafka.js";
/**
* IAM 根模块。
*
* 装配:
* - IamModule业务
* - HealthModule健康检查
* - OutboxModule事务性事件发布I5 裁决)
* - AuthMiddleware从 Gateway 注入的 x-user-* 头部解析用户身份)
* - PermissionGuardAPP_GUARDDB 驱动 + Redis 缓存I3 裁决)
*/
@Module({
imports: [
IamModule,
HealthModule,
OutboxModule.forRoot({
config: {
tableName: "iam_outbox",
kafkaTopic: IAM_KAFKA_TOPICS.USER_EVENTS,
pollIntervalMs: 1000,
batchSize: 20,
maxRetryCount: 5,
retryBackoffMs: 1000,
},
db: getDbInstance(),
kafkaProducer: getKafkaProducer(),
}),
],
providers: [
{ provide: APP_GUARD, useClass: PermissionGuard },
LifecycleService,
],
})
export class AppModule implements NestModule, OnModuleInit {
private readonly logger = new Logger(AppModule.name);
async onModuleInit(): Promise<void> {
// 连接 Kafka producerOutbox 投递前置依赖)
try {
await connectKafkaProducer();
this.logger.log("Kafka producer connected");
} catch (error) {
this.logger.error(
`Kafka producer connect failed: ${error instanceof Error ? error.message : String(error)}`,
);
}
}
configure(consumer: MiddlewareConsumer): void {
// AuthMiddleware 应用于需要鉴权的 /v1/iam 路由
// 公开端点register/login/refresh/jwks/health/metrics不走此中间件
consumer
.apply(AuthMiddleware)
.forRoutes(
"v1/iam/me",
"v1/iam/logout",
"v1/iam/viewports",
"v1/iam/permissions/effective",
"v1/iam/children",
"v1/iam/roles",
"v1/iam/permissions",
"v1/iam/audit",
);
}
}