【发布时间】:2021-12-24 04:33:18
【问题描述】:
我通过 NestJS 使用 TypeORM 连接到 PostgreSQL 数据库。对于我与数据库建立的每个连接,我都需要“SET ROLE my-service”,最好只在建立连接时进行一次。我有哪些选择?
我试图找到一种使用传递给 TypeOrmModule.forRoot() 的配置的方法。我已经考虑过我可以提前向 PostgreSQL 客户端发出指令的可能性,但我对如何做到这一点没有强烈的意识。
【问题讨论】:
我通过 NestJS 使用 TypeORM 连接到 PostgreSQL 数据库。对于我与数据库建立的每个连接,我都需要“SET ROLE my-service”,最好只在建立连接时进行一次。我有哪些选择?
我试图找到一种使用传递给 TypeOrmModule.forRoot() 的配置的方法。我已经考虑过我可以提前向 PostgreSQL 客户端发出指令的可能性,但我对如何做到这一点没有强烈的意识。
【问题讨论】:
请根据您未填写的问题滚动到更新 2。
injectable service
您可以将服务SomeTypeOrmConfigService 创建为@Injectable(),然后像这样注入它。
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';
// create your injectable here
@Injectable()
export class SomeTypeOrmConfigService implements TypeOrmOptionsFactory {
constructor(private configService: ConfigService) {}
createTypeOrmOptions(): TypeOrmModuleOptions {
return {
type: 'mysql',
host: this.configService.get('DATABASE_HOST'),
username: this.configService.get('DATABASE_USERNAME'),
password: this.configService.get('DATABASE_PASSWORD'),
};
}
}
.env 中,或 b) 另一种方法 database.provider.ts 文件并将复制的 ans./credit 导出到 from here
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
export const databaseProviders = [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
host: configService.get('PGHOST'),
port: +configService.get<number>('PGPORT'),
username: configService.get('PGUSER'),
password: configService.get('PGPASSWORD'),
database: configService.get('PGDATABASE'),
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: false,
logging: true,
}),
}),
];
然后在你的database.module.ts中导入它
import { databaseProviders } from './database.provider';
import { DatabaseService } from './database.service';
import { Module } from '@nestjs/common';
@Module({
imports: [...databaseProviders],
providers: [DatabaseService],
exports: [...databaseProviders],
})
export class DatabaseModule {}
仅此而已,您可以根据需要在 database.provider.ts 中添加多个连接,此外,不要忘记在根模块中创建 .env 并导入数据库模块。
简而言之.. 我认为你错过了 a) 像 nestjs-session 这样的会话模块,一旦你使用它,你就可以选择 b) 将它缓存在你的角色中与您的会话对象
第一步:使用nestjs-session
第 2 步:现在您可以在 request 的 session 属性对象中访问/使用 role
第 3 步:然后您可以在 NestSessionOptions 的帮助下将其设为可注射工厂或用户工厂
npm i nestjs-roles
// role.enum.ts
export enum Role {
ADMIN = 'ADMIN',
USER = 'USER',
MODERATOR = 'MODERATOR',
}
nestjs-session 并在请求的会话属性对象中保留角色。那么使用 getRole 回调创建守卫:// roles.guard.ts
import { ExecutionContext } from '@nestjs/common';
import { createRolesGuard } from 'nestjs-roles';
import { Role } from './role.enum';
function getRole(context: ExecutionContext) {
const { session } = context.switchToHttp().getRequest();
if (!session) {
return;
}
return (session as { role?: Role }).role;
}
export const Roles = createRolesGuard<Role>(getRole);
// bootstrap.ts
import { NestFactory, Reflector } from '@nestjs/core';
import { Roles } from './roles.guard';
const app = await NestFactory.create(AppModule);
const reflector = app.get<Reflector>(Reflector);
app.useGlobalGuards(new Roles(reflector));
// secrets.controller.ts
import { Roles } from './roles.guard';
@Controller('secrets')
@Roles.Params(true) // setup access on Controller for users with any existing role
export class SecretsController {
@Get('my')
async readMy() {
// ...
}
@Patch(':id')
@Roles.Params(Role.ADMIN) // override access on certain handler
async update() {
// ...
}
}
【讨论】: