Соединение углового HTTP с контроллером TypeORM / Nestjs - это работает, но безопасно?

Я нервничаю по поводу разработки безопасности в моем коде. У меня этот код работает должным образом, но является ли он оптимальным для обеспечения безопасности или есть более эффективные способы выполнения CRUD и запросов? Я включаю полный CRUD и несколько запросов здесь в качестве примеров для других. Пока что в Интернете практически ничего не говорится о том, как Angular и Nestjs / TypeORM объединяются. Это должно помочь заполнить этот пробел для тех из нас, кто новичок на стороне сервера. Я хотел бы предложения для улучшения и обсуждения, так как я не уверен, что я понимаю это правильно.

Ниже представлены как параметры поиска репозитория TypeORM, так и метод Query Builder. Не уверен, что лучше или если это имеет значение.

Угловой httpService.service

// ---- GET all records. ----

  public getAllRecords(dbTable: string): Observable<any> {
    return this.http
      .get<any>(`${this.api}${dbTable}`);
  }


// ---- CREATE new record ---

  public addRecord(dbTable: string, recordData):  Observable<any> {
    return this.http
      .post(`${this.api}${dbTable}`, recordData, {headers: this.headers});
  }


// ---- FETCH record detail for editing or viewing. ----

  public getRecordById(dbTable: string, recordId: number): Observable<any> {
    return this.http
      .get<any>(`${this.api}${dbTable}/${recordId}`);
  }


// ---- UPDATES an existing record ----

  public updateRecord(dbTable: string, recordId: number, recordUpdate): Observable<any> {
    return this.http
      .patch(`${this.api}${dbTable}/${recordId}`, recordUpdate, {headers: this.headers});
  }


// ---- DELETES a single record. ----

  public deleteRecord(dbTable: string, recordId: number):  Observable<any> {
    return this.http
      .delete(`${this.api}${dbTable}?id=${recordId}`, {headers: this.headers});
  }


  // ---------------- QUERIES ------------------------------



  // --------- INCREMENTAL SEARCH --------

  //  Called by the Mat Data Table filter to search db by user name.
  public nameSearch(dbTable, column, terms) {
    return terms.pipe(
      tap(x => console.log('3 service called')),
      debounceTime(300),
      distinctUntilChanged(),
      switchMap(term => {
        console.log('4 term: ', term);
        const url = `${this.api}${dbTable}/${column}/${term}`;
        return this.http.get(url);
      }),
      catchError((error: any) => {
        console.error(error);
        return of();
      }),
    );
  }


  // ------------- SEARCH COUNTRIES ---------------------
  //  Called from main components to search for users by country.

  public searchCountries(dbTable, column, country): Observable<any> {
    return this.http.get(`${this.api}${dbTable}/${column}/${country}`);
  }

TypeORM и контроллер Nestjs, конечная точка API:

@Controller('api/members')  // /members route
export class MembersController {
  constructor(private readonly membersService: MembersService) {}


  /* --------------- CRUD -------------------- */


  @Get()
  async findAll(): Promise<Members[]> {
    return await this.membersService.findAll();
  }

  @Get('/:id')
  async findItem(@Param() recordId): Promise<Members> {
    return this.membersService.findItem(recordId.id);
  }

  @Post()  // Adding the dto type to recordData made no difference.
  async addItem(@Req() req, @Body() recordData): Promise<Members> {

    const result: Members = await this.membersService.addItem(recordData);
    if (!result)
      throw new HttpException('Error adding new Member', HttpStatus.BAD_REQUEST);
    return result;
  }

  @Patch('/:id')
  async updateItem(@Param() recordId: number, @Body() recordUpdate) {
    const result = await this.membersService.updateItem(recordId, recordUpdate);
    if (!result)
      throw new HttpException('Error updating Member', HttpStatus.BAD_REQUEST);
    return result;
  }

  @Delete()
  async deleteItem(@Query() recordId) {
    return await this.membersService.deleteItem(recordId.id);
  }



  /* ---------------------  QUERIES -------------------- */


  // Called from Angular last name search() in http.service. User inputs words by letter to search.

  @Get('/last_name/:entry')
  public async wordSearch(@Param('entry') entry) {
    const result = await this.membersService.wordSearch(entry);
    if (!result)
      throw new HttpException('Error searching last name', HttpStatus.BAD_REQUEST);
    return result;
  }


  // Called from searchCountries in Angular http.service.
  @Get('/country/:country')
  public async searchCountries(@Param('country') country) {
    const result = this.membersService.searchCountries(country);
    if (!result)
      throw new HttpException('Error searching last name', HttpStatus.BAD_REQUEST);
    return result;
  }
}

1 ответ

Вы можете проверить любой пользовательский ввод от @Param() а также @Body() параметры. Как правило, вы можете иметь некоторые поля для внутреннего управления, которые не должны контролироваться пользователем.

Например, "удаленное" поле или поля только для чтения с некоторой статистикой.

Посмотрите на пакеты классов-трансформеров и классов-валидаторов

Другие вопросы по тегам