安全性多公司关联

时间:2019-02-21 01:28:49

标签: mysql typescript rest orm typeorm

问题:公司可以仅通过通知关系中的id来关联与其不相关的记录

方案::我的api是多公司的,每个公司都管理您的记录(产品,订单...),但是这些公司只能查看和使用属于它们的记录。但是,可以在订单中输入其他公司的产品ID,而不应该

示例:如果苹果公司试图通知Google Pixel应该出现一些错误消息,则只能通知其订单中的iPhone产品

观察:我希望在保存之前不需要验证与该订单相关的每条记录,因为我的实际模式具有多个关系(与一个订单相关联的20个表,一些2级层叠)仅是一个小例子。在数据库中搜索每种产品并验证其是否属于公司将非常复杂。我认为可以通过一些索引设置来阻止此记录

问题:如何防止将其他公司的记录与当前公司记录相关联,甚至在报告正文请求时也要报告ID?

感谢您的帮助,因为在这种情况下我正在生产一个系统。

company.entity.ts

@Entity()
export class Company {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @OneToMany(() => Product, (product) => product.company)
  products: Product[];

  @OneToMany(() => Order, (order) => order.company)
  orders: Order[];
}

product.entity.ts

@Entity()
export class Product {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  description: string;

  @ManyToOne(() => Company, (company) => company.products)
  company: Company;
}

order.entity.ts

@Entity()
export class Order {

  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  description: string;

  @ManyToOne(() => Company, (company) => company.orders)
  company: Company;

  @ManyToMany(() => Product)
  @JoinTable()
  products: Product[];
}

order.controller.ts

@Controller('orders')
export class OrderController {

  constructor(
    @InjectRepository(Order)
    public repository: Repository<Order>,
  ) { }

  @Post()
  public async create(@Body() body: Order): Promise<Order> {
    body.id = undefined;
    body = await this.repository.save(body);
    return await this.repository.findOne(body.id, { relations: ['products'] });
  }

  @Put(':id')
  public async update(@Param('id') id, @Body() body: Order): Promise<Order> {
    body.id = Number(id);
    await this.repository.save(body);
    return await this.repository.findOne(id, { relations: ['products'] });
  }
}

公司表

  • id :1 说明:Apple
  • id :2个说明:Google

项目表

  • ID :1 说明:iPhone companyId: 1
  • id :2 说明:Google Pixel companyId :2

POST http://localhost:3040/orders 正文要求: 观察:在这里,用户通知iPhone是他知道的产品,并强制将产品ID 2设为未知产品,因为api GET会验证哪些产品对Apple可见,在这种情况下,只有iPhone

{
    "company": 1,
    "description": "Order 001",
    "products": [
        {
            "id": 1,
            "description": "iPhone"
        },
        {
            "id": 2
        }
    ]
}

身体反应: 观察:即使通知另一家公司的产品,在api退还时也会显示Google像素,该像素无法按照苹果的订单进行记录。在这里您应该有一条错误消息

{
    "id": 2,
    "description": "Order 001",
    "products": [
        {
            "id": 1,
            "description": "iPhone"
        },
        {
            "id": 2,
            "description": "Google Pixel"
        }
    ]
}

结果表

订单表

  • id :1 说明:订单001 companyId :1

订购产品表

  • orderId :2 productId :1
  • orderId :2 productId :2

1 个答案:

答案 0 :(得分:0)

有两个问题要解决。首先是订单和产品之间的多对多关系并不限制产品的公司。您可能可以使用正确的装饰器来做到这一点,我相信您可以在@JoinTable装饰器中指定表和列信息。

第二个问题是需要一种将API调用程序与其所属公司关联的方法。您可以通过使用JWT进行身份验证并将公司ID嵌入到JWT的有效负载中来实现。

希望这会有所帮助。