Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Angular HTTP与TypeORM Controller/Nestjs连接起来-这些工作正常但安全吗?_Angular_Typeorm_Nestjs - Fatal编程技术网

将Angular HTTP与TypeORM Controller/Nestjs连接起来-这些工作正常但安全吗?

将Angular HTTP与TypeORM Controller/Nestjs连接起来-这些工作正常但安全吗?,angular,typeorm,nestjs,Angular,Typeorm,Nestjs,我对在代码中设计安全性感到紧张。我有这段代码可以正常工作,但它是安全性的最佳选择还是有更好的方法来执行CRUD和查询?我在这里包括完整的CRUD和几个查询,作为其他示例。到目前为止,关于Angular和Nestjs/TypeORM是如何结合在一起的,Web上几乎没有这方面的内容。这将有助于填补我们这些服务器端新手的空白。我很想得到改进和讨论的建议,因为我没有信心我做对了 下面是TypeORM存储库查找选项方法和查询生成器方法。不确定哪一个是最好的,或者它是否重要 角度httpService.se

我对在代码中设计安全性感到紧张。我有这段代码可以正常工作,但它是安全性的最佳选择还是有更好的方法来执行CRUD和查询?我在这里包括完整的CRUD和几个查询,作为其他示例。到目前为止,关于Angular和Nestjs/TypeORM是如何结合在一起的,Web上几乎没有这方面的内容。这将有助于填补我们这些服务器端新手的空白。我很想得到改进和讨论的建议,因为我没有信心我做对了

下面是TypeORM存储库查找选项方法和查询生成器方法。不确定哪一个是最好的,或者它是否重要

角度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}`);
  }
/----获取所有记录----
publicGetAllRecords(dbTable:string):可观察{
返回此文件。http
.get(`this.api}${dbTable}`);
}
//----创建新记录---
public addRecord(dbTable:string,recordData):可观察{
返回此文件。http
.post(`this.api}${dbTable}`,recordData,{headers:this.headers});
}
//----获取记录详细信息以进行编辑或查看----
public getRecordById(dbTable:string,recordId:number):可观察{
返回此文件。http
.get(`${this.api}${dbTable}/${recordId}`);
}
//----更新现有记录----
公共更新记录(dbTable:string,recordId:number,recordUpdate):可观察{
返回此文件。http
.patch(`${this.api}${dbTable}/${recordId}`,recordUpdate,{headers:this.headers});
}
//----删除单个记录----
公共deleteRecord(dbTable:string,recordId:number):可观察{
返回此文件。http
.delete(`this.api}${dbTable}?id=${recordId}`,{headers:this.headers});
}
//------------查询------------------------------
//------增量搜索--------
//由Mat数据表筛选器调用,以按用户名搜索数据库。
公共名称搜索(数据库表、列、术语){
退货条件.烟斗(
点击(x=>console.log('3个服务被调用')),
去BounceTime(300),
distinctUntilChanged(),
开关映射(术语=>{
console.log('4术语:',术语);
常量url=`${this.api}${dbTable}/${column}/${term}`;
返回此.http.get(url);
}),
catchError((错误:任意)=>{
控制台错误(error);
返回();
}),
);
}
//------搜索国家/地区---------------------
//从主要组件调用以按国家/地区搜索用户。
公共搜索国家(数据库表、列、国家):可观察{
返回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;
  }
}
@Controller('api/members')///成员路由
导出类成员控制器{
构造函数(私有只读成员服务:成员服务){}
/*------------积垢------------------*/
@得到()
异步findAll():承诺{
return等待this.membersService.findAll();
}
@获取(“/:id”)
异步findItem(@Param()recordId):承诺{
返回此.membersService.findItem(recordId.id);
}
@Post()//将dto类型添加到recordData没有任何区别。
异步附加项(@Req()Req,@Body()recordData):承诺{
const result:Members=wait this.membersService.addItem(recordData);
如果(!结果)
抛出新的HttpException('Error adding new Member',HttpStatus.BAD_REQUEST);
返回结果;
}
@修补程序(“/:id”)
异步更新项(@Param()recordId:number,@Body()recordUpdate){
const result=wait this.membersService.updateItem(recordId,recordUpdate);
如果(!结果)
抛出新的HttpException(“更新成员时出错”,HttpStatus.BAD_请求);
返回结果;
}
@删除()
异步删除项(@Query()recordId){
return wait this.membersService.deleteItem(recordId.id);
}
/*----------------查询-----------------*/
//从http.service中的姓氏搜索()调用。用户按字母输入单词进行搜索。
@获取('/last_name/:entry')
公共异步字搜索(@Param('entry')条目){
const result=等待this.membersService.wordSearch(条目);
如果(!结果)
抛出新的HttpException('搜索姓氏时出错',HttpStatus.BAD_请求);
返回结果;
}
//从http.service中的searchCountries调用。
@获取(“/country/:country”)
公共异步搜索国家(@Param('country')国家){
const result=this.membersService.searchCountries(国家/地区);
如果(!结果)
抛出新的HttpException('搜索姓氏时出错',HttpStatus.BAD_请求);
返回结果;
}
}

您可能需要验证来自
@Param()
@Body()
参数的任何用户输入。通常,您可以在内部管理一些不应由用户控制的字段

例如,“已删除”字段,或带有某些统计信息的只读字段


看一看和包装

真正需要的是一篇博客文章,解释这一切是如何运作的,但我还不够胜任。谢谢你Alexey。我正在用如下方式验证我的表单:
first\u name:['',Validators.required],
我刚刚为唯一用户名制作了一个自定义验证程序,本周还制作了更多。typestack包似乎完成了Angular的部分或全部功能,但我不是这方面的专家。很高兴看到普莱洛克的贡献。我给他寄了打字的钱。