Các Lớp Cơ sở Ứng dụng
Tổng quan
@nx/core cung cấp một lớp cơ sở trừu tượng, BaseApplication, chứa hạ tầng mà mọi dịch vụ backend BANA dùng chung: middleware CORS và giới hạn body, endpoint health check, tài liệu Swagger/OpenAPI, phục vụ tệp tĩnh, đăng ký IdentityNetworkService, và luồng khởi tạo preConfigure().
Các dịch vụ không kế thừa trực tiếp BaseApplication. Chúng kế thừa một trong hai lớp con cụ thể dựa trên vai trò trong chuỗi tin cậy JWT:
IssuerApplication- chỉ được kế thừa bởi@nx/identity. Ký JWT (JWKS issuer) và phục vụ tập khóa công khai tại/jw-certs.VerifierApplication- được kế thừa bởi 13 dịch vụ IGNIS còn lại. Xác minh JWT dựa trên endpoint JWKS của identity.
Lớp con thứ ba, DefaultApplication, là legacy và không được dùng - không có gì kế thừa nó. Nó có trước cặp Issuer/Verifier và dùng token JWS đối xứng, không có phân quyền.
Nguồn:
| Tệp | Lớp |
|---|---|
packages/core/src/application/base.ts | BaseApplication (trừu tượng, dùng chung) |
packages/core/src/application/issuer.ts | IssuerApplication |
packages/core/src/application/verifier.ts | VerifierApplication |
packages/core/src/application/default.ts | DefaultApplication (legacy) |
Xem tham chiếu IGNIS Application để biết chi tiết về
BaseApplicationcủa IGNIS mà lớp cơ sở của@nx/coremở rộng.
Phân cấp Lớp
| Lớp cơ sở | Được kế thừa bởi | Xác thực | Phân quyền |
|---|---|---|---|
BaseApplication (trừu tượng) | - (dùng chung) | khai báo configureAuthentication() | khai báo configureAuthorization() |
IssuerApplication | chỉ @nx/identity | JWKS issuer (ký, phục vụ /jw-certs) | Casbin (scoped) |
VerifierApplication | commerce, finance, inventory, sale, signal, payment, pricing, ledger, invoice, licensing, outreach, taxation, helpdesk | JWKS verifier (xác minh dựa trên JWKS của identity) | Casbin (scoped) |
DefaultApplication | không có gì (legacy) | JWS đối xứng | không có |
Định nghĩa Lớp
BaseApplication là trừu tượng: nó triển khai vòng đời dùng chung và để phần xác thực/phân quyền cho các lớp con.
import { BaseApplication as IgnisBaseApplication, IApplicationInfo } from '@venizia/ignis';
import { ValueOrPromise } from '@venizia/ignis-helpers';
export abstract class BaseApplication extends IgnisBaseApplication {
protected applicationRoles: string[] = [];
// Implemented per subclass (Issuer / Verifier / Default)
protected abstract configureAuthentication(): ValueOrPromise<void>;
protected abstract configureAuthorization(): ValueOrPromise<void>;
// Shared lifecycle
override getAppInfo(): IApplicationInfo;
preConfigure(): void;
async postConfigure(): Promise<void>;
override async setupMiddlewares(): Promise<void>;
staticConfigure(): void;
// Registration methods (override in child packages)
configureDatasources(): void;
configureRepositories(): void;
configureServices(): void; // registers IdentityNetworkService
configureComponents(): void; // HealthCheck + Swagger
configureSecurity(): void; // -> configureAuthentication() + configureAuthorization()
configureControllers(): void;
}Vòng đời và Trình tự Khởi động
Thứ tự Gọi preConfigure()
preConfigure() chạy các phương thức đăng ký theo thứ tự cố định. Ở chế độ chạy MIGRATE, nó dừng sớm sau repository (migration chỉ cần truy cập cơ sở dữ liệu); ngược lại tiếp tục qua service, component, security, và controller.
preConfigure() {
this.applicationRoles = this.getApplicationRoles();
this.configureDatasources(); // 1. Data sources
this.configureRepositories(); // 2. Repositories
if (this.getApplicationRunMode() !== ApplicationRunModes.MIGRATE) {
this.configureServices(); // 3. Services (IdentityNetworkService)
this.configureComponents(); // 4. Components (HealthCheck, Swagger)
this.configureSecurity(); // 5. Authentication + Authorization
this.configureControllers(); // 6. Controllers
}
}Trình tự Khởi động Đầy đủ
Cấu hình Middleware
setupMiddlewares() nằm trong lớp cơ sở dùng chung. Nó tùy chọn cắm một middleware tracing HTTP (chỉ khi telemetry được khởi tạo bởi bootstrapApplication), rồi đăng ký CORS và một giới hạn body.
CORS
cors: {
enable: true,
path: '*',
origin: '*',
allowMethods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'],
allowHeaders: [/* see table below */],
exposeHeaders: [/* see table below */],
maxAge: 86_400, // 24 hours
credentials: true,
}Các Header Yêu cầu Được phép:
| Header | Hằng số IGNIS |
|---|---|
Authorization | HTTP.Headers.AUTHORIZATION |
Content-Type | HTTP.Headers.CONTENT_TYPE |
X-Request-Channel | HTTP.Headers.REQUEST_CHANNEL |
X-Count-Data | HTTP.Headers.REQUEST_COUNT_DATA |
X-Device-Info | HTTP.Headers.REQUEST_DEVICE_INFO |
X-Tracing-Id | HTTP.Headers.REQUEST_TRACING_ID |
timezone | Tùy chỉnh |
timezone-offset | Tùy chỉnh |
x-auth-provider | Tùy chỉnh |
x-forward-for | Tùy chỉnh |
x-locale | Tùy chỉnh |
x-merchant-id | Tùy chỉnh (phạm vi merchant đang hoạt động) |
x-real-ip | Tùy chỉnh |
Các Header Phản hồi Được phơi bày:
| Header | Hằng số IGNIS |
|---|---|
Content-Disposition | HTTP.Headers.CONTENT_DISPOSITION |
Content-Length | HTTP.Headers.CONTENT_LENGTH |
Content-Range | HTTP.Headers.CONTENT_RANGE |
Content-Type | HTTP.Headers.CONTENT_TYPE |
X-Count-Data | HTTP.Headers.RESPONSE_COUNT_DATA |
X-Response-Format | HTTP.Headers.RESPONSE_FORMAT |
x-custom-header | Tùy chỉnh |
Giới hạn Body
bodyLimit: {
enable: true,
path: '*',
maxSize: 100 * 1024 * 1024, // 100 MB
onError: c => c.json({}, HTTP.ResultCodes.RS_4.ContentTooLarge), // HTTP 413
}Thiết lập Thành phần
Health Check
Được đăng ký tại endpoint /health. Trả về thông tin trạng thái ứng dụng.
this.bind<IHealthCheckOptions>({
key: HealthCheckBindingKeys.HEALTH_CHECK_OPTIONS,
}).toValue({
restOptions: { path: '/health' },
});
this.component(HealthCheckComponent);Xem tham chiếu IGNIS Health Check để biết định dạng phản hồi và tùy chỉnh.
Swagger / OpenAPI
Cung cấp ba endpoint cho tài liệu API, sử dụng trình hiển thị Swagger UI (ui.type: 'swagger'):
| Đường dẫn | Mô tả |
|---|---|
/doc | Đường dẫn cơ sở tài liệu |
/openapi.json | Đặc tả OpenAPI 3.0 (JSON) |
/explorer | Swagger UI |
this.bind<ISwaggerOptions>({ key: SwaggerBindingKeys.SWAGGER_OPTIONS }).toValue({
restOptions: {
base: { path: '/doc' },
doc: { path: '/openapi.json' },
ui: { path: '/explorer', type: 'swagger' },
},
explorer: {
openapi: '3.0.0',
info: {
title: 'API Documentation',
version: this.getAppInfo().version,
description: 'NEXPANDO - Seller API documentation',
},
servers: [
{
url: applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_APPLICATION_EXPLORER_URL),
description: 'Application Server URL',
},
],
},
});
this.component(SwaggerComponent);Xem tham chiếu IGNIS Swagger để biết đầy đủ tùy chọn.
Thiết lập Bảo mật
configureSecurity() được lớp cơ sở dùng chung và chỉ ủy thác cho hai phương thức trừu tượng mà mỗi lớp con triển khai:
configureSecurity(): void {
this.configureAuthentication();
this.configureAuthorization();
}Xác thực theo Lớp con
| Lớp con | Chiến lược JWT | JOSEStandards | Ghi chú |
|---|---|---|---|
IssuerApplication | JWKSIssuerAuthenticationStrategy | JWKS (mode ISSUER) | Ký bằng khóa riêng PEM; công bố khóa tại /jw-certs |
VerifierApplication | JWKSVerifierAuthenticationStrategy | JWKS (mode VERIFIER) | Xác minh dựa trên APP_ENV_IDENTITY_SERVICE_BASE_URL + /jw-certs |
DefaultApplication | JWSAuthenticationStrategy | JWS | Secret đối xứng legacy; không dịch vụ nào dùng |
Cả ba đều gọi helper dùng chung bindBasicAuthentication(), đăng ký AuthenticateComponent, và thêm một chiến lược Basic ủy thác cho dịch vụ Identity.
Xác thực Basic (dùng chung)
bindBasicAuthentication() (định nghĩa trên lớp cơ sở) ủy thác việc xác minh thông tin đăng nhập cho dịch vụ Identity thông qua IdentityNetworkService.signIn():
protected bindBasicAuthentication(): void {
this.bind<TBasicTokenServiceOptions>({ key: AuthenticateBindingKeys.BASIC_OPTIONS }).toValue({
verifyCredentials: ({ credentials }) => {
const identityNetworkService = this.get<IdentityNetworkService>({
key: BindingKeys.build({
namespace: BindingNamespaces.SERVICE,
key: IdentityNetworkService.name,
}),
});
return identityNetworkService.signIn({
identifier: { scheme: 'username', value: credentials.username },
credential: { scheme: 'basic', value: credentials.password },
});
},
});
}Phân quyền (Casbin)
IssuerApplication và VerifierApplication đều đăng ký IGNIS AuthorizeComponent với một Casbin enforcer scoped (ScopedCasbinAdapter, model domain-scoped, defaultDecision: DENY, alwaysAllowRoles = SUPER_ADMIN / ADMIN / OPERATOR) và một domain resolver scoped theo merchant điều khiển bởi header x-merchant-id. DefaultApplication.configureAuthorization() để trống.
Luồng Xác thực
Xem tham chiếu IGNIS Authentication để biết chi tiết chiến lược.
Phục vụ Tệp Tĩnh
staticConfigure() phục vụ các tệp từ thư mục public/ của gói @nx/core:
staticConfigure(): void {
this.static({ folderPath: path.join(__dirname, '../../public') });
}Cách Mở rộng trong Các Gói Con
Mỗi dịch vụ khai báo lớp Application kế thừa VerifierApplication (hoặc IssuerApplication cho @nx/identity) và ghi đè các phương thức đăng ký, gọi super trước:
// packages/sale/src/application.ts
import { VerifierApplication, PostgresCoreDataSource } from '@nx/core';
export class Application extends VerifierApplication {
override configureDatasources(): void {
super.configureDatasources();
this.dataSource(PostgresCoreDataSource);
}
override configureRepositories(): void {
super.configureRepositories();
this.repository(SaleOrderRepository);
this.repository(SaleOrderItemRepository);
}
override configureServices(): void {
super.configureServices(); // IdentityNetworkService
this.service(SaleOrderService);
this.service(CheckoutService);
}
override async postConfigure(): Promise<void> {
await super.postConfigure();
// Run after all components are bound
}
}Luôn gọi super
Khi ghi đè bất kỳ phương thức đăng ký nào, gọi super.<method>() trước để giữ lại các đăng ký mặc định (IdentityNetworkService, HealthCheck, Swagger, JWKS/Basic auth).
Biến Môi trường
| Biến | Dùng bởi | Bắt buộc | Mô tả |
|---|---|---|---|
APP_ENV_APPLICATION_SECRET | Tất cả | Có | Secret cấp ứng dụng |
APP_ENV_JWKS_ALGORITHM | Issuer | Không | Thuật toán ký (mặc định ES256) |
APP_ENV_JWKS_PRIVATE_KEY | Issuer | Có | Khóa ký riêng PEM |
APP_ENV_JWKS_PUBLIC_KEY | Issuer | Có | Khóa công khai PEM |
APP_ENV_JWKS_REST_PATH | Issuer + Verifier | Không | Đường dẫn endpoint JWKS (mặc định /jw-certs) |
APP_ENV_IDENTITY_SERVICE_BASE_URL | Verifier (+ Basic) | Có | URL cơ sở dịch vụ Identity (nguồn JWKS + ủy thác Basic) |
APP_ENV_JWT_EXPIRES_IN | Issuer | Có | Thời gian hết hạn token tính bằng giây |
APP_ENV_APPLICATION_ROLES | Tất cả | Không | Danh sách định danh vai trò phân cách bằng dấu phẩy |
APP_ENV_APPLICATION_EXPLORER_URL | Tất cả | Không | URL server hiển thị trong Swagger explorer |
Legacy: DefaultApplication
DefaultApplication (application/default.ts) chỉ được giữ lại để tham khảo. Nó cấu hình một token JWS đối xứng (APP_ENV_JWT_SECRET) qua JWSAuthenticationStrategy và để trống configureAuthorization(). Không dịch vụ nào kế thừa nó - mọi dịch vụ dùng IssuerApplication hoặc VerifierApplication thay vào đó. Không dùng nó cho các gói mới.