使用任何 ORM 从 Nestjs 连接到 Azure Postgresql 灵活服务器数据库

问题描述 投票:0回答:1

我们正在构建一个 Nestjs 应用程序,该应用程序使用 Typeorm 连接到 Azure Postgresql 灵活数据库服务器。我们遵循使用托管身份和 Entra 令牌的无密码方法。我们的应用程序能够连接到数据库,但在令牌过期后(在我们的例子中为 24 小时),我们的应用程序会因数据库连接未自动刷新而关闭。

还有其他人遇到过这个问题吗?

我们尝试在 23 小时后使用 https://learn.microsoft.com/en-us/javascript/api/overview/azure/identity-readme?view=azure-node-latest 刷新令牌,但我们可以看到即使在 24 小时后也没有生成新的令牌。

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ManagedIdentityCredential } from '@azure/identity';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      useFactory: async () => {
        const credential = new ManagedIdentityCredential(); // Use ManagedIdentityCredential

        // Fetch the access token
        const tokenResponse = await credential.getToken('https://ossrdbms-aad.database.windows.net/.default');

        return {
          type: 'postgres',
          host: '<YOUR_DATABASE_SERVER_NAME>.postgres.database.azure.com', // Replace with your server name
          port: 5432,
          username: '<YOUR_AAD_USER>@<YOUR_DATABASE_SERVER_NAME>', // Replace with your Azure AD user
          password: tokenResponse.token, // Use the fetched access token as the password
          database: '<YOUR_DATABASE_NAME>', // Replace with your database name
          ssl: { rejectUnauthorized: false }, // Adjust based on your SSL requirements
          entities: [/* Your entities here */],
          synchronize: true, // Set to false in production
        };
      },
    }),
  ],
})
export class DatabaseModule {}
import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module'; // Adjust the path as necessary

@Module({
  imports: [
    DatabaseModule, // Import the DatabaseModule here
    // Other modules can be added here as needed
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}
nestjs azure-managed-identity azure-postgresql nestjs-typeorm password-less
1个回答
0
投票

我会使用 cron 作业将

dataSource
注入到服务中,以定期刷新令牌。但是,有一些警告:如果在重新启动连接时收到请求,它们可能会失败。

以下是如何刷新令牌并使用托管身份的新访问令牌重新初始化

DataSource
的示例:

@Injectable()
export class TokenRefresher {
  constructor(
    private readonly dataSource: DataSource
  ) {}

  @Cron('*/15 * * * * *')
  async refresh(): Promise<Credentials[]> {
 

    // here custom logic to restart the database
    const destroyDatabase = true;

    if (destroyDatabase) {
      const credential = new ManagedIdentityCredential(); // Use ManagedIdentityCredential

      // Fetch the access token
      const tokenResponse = await credential.getToken(
        "https://ossrdbms-aad.database.windows.net/.default"
      );

      await this.dataSource.destroy();
      this.dataSource.setOptions({
        password: tokenResponse.password,
      });
      await this.dataSource.initialize();
    }
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.