Multi Tenant Architecture with Loopback

We define loopback models for achieving multi tenancy, such that every Model passes through organization model and the data accessible is only specific to particular organization.

We restrict access to all direct methods for each model and only make them accessible through organization model. This way, only org specific data could be returned.

Define models and their base

In loopback when you create a model with the model generator, you choose a base model, that is, the model that your model will “extend” and from which it will inherit methods and properties. Read more about models

Since user model is the most restrictive and protected model, it is difficult to hack into unauthorized data, we chose it to be the base for our organization model.

Also the concept of $owner ACLs only works for user models and its inheritors, so that is a huge technical reason for picking this model as well.

Relationships
  • Users -> Belongs To - Organization
  • Organization -> Has Many - Users
  • Products -> Belongs To - Organization
  • Organization -> Has Many - Products
  • Catalog -> Belongs To - Organization
  • Organization -> Has Many - Catalog
  • Orders -> Belongs To - Organization
  • Organization -> Has Many - Orders
Sample Queries
  1. Create product for Organization

    Organization.product.create({
     name: "Product-A",
     desc: "This product belongs to org-a"
    })
    .then(function(success){
     ...
    })
    .catch(function(err){
     ...
    });
    
  2. Fetch product for Organization

    Organization.prodcut.find({
     where:{
         name: "Product-A"
     } 
    })
    .then(function(success){
     ...
    })
    .catch(function(err){
     ...
    });
    
Invalid or disabled Queries

Following samples will give 401 Authorization Required error as these should be disabled from the backend.

  1. Create product for Organization
    Product.create({
     name: "Product-A",
     desc: "This product belongs to org-a"
    })
    
  2. Fetch product for Organization
    Prodcut.find({
     where:{
         name: "Product-A"
     } 
    }}
    

Why? Remember, earlier we decided to:

restrict access to all direct methods for each model and only make them accessible through organization model. This way, only org specific data can be returned.

To read more about how to disable methods in loopback you can refer to this article.

results matching ""

    No results matching ""