Separating Data

Separating and restricting access to data are two common features of building a backend. Separating data is crucial for multi-tenant systems. It means that even though all your users have data in the same table, they are only able to see and access the data that belongs to them.

Restricting Access (Role-Based Access Control) takes this to another level if, for example, there are special roles assigned to users like an admin who may have permission to access more data than a standard user. You can read more on restricting access or RBAC by clicking the link at the beginning of this paragraph.

Separating Data Example 1

For this example, we have three users in our user table: Steph, Klay, and Jordan.

There is also an items table. Each item belongs to a user.

How to enforce a user only sees the items that belongs to them

Here we have an API endpoint, which gets all the items from the items table. The first step is to require user authentication on the endpoint.

Now that authentication is required, the next step is to open the Query All Records function and add an expression to the by custom query section.

db: items.user_id = auth id

When we go to run the API endpoint in Run&Debug, an auth token is required to run the API. In Xano, we can easily search for a user to use a auth token for testing. In your application, the user will need to authenticate first by logging in or signing up.

Let's select user 2, Klay and run the API endpoint:

The result is all the items associated with user id = 2:

Added layer of security with precondition

We can add an additional layer of security with the use of preconditions.

First, use a Get Record on the user table with a field value of the auth id.

Then use a precondition to enforce the auth ID is equal to the id from the Get Record.

auth id = var:

How to enforce the user can only edit data that belongs to them

When it comes to editing data, the function stack will also use a precondition. The API endpoint will once again require authentication.

First, we need to Get the Record of the item that the user wants to edit.

Getting the existing record allows us to check if it belongs to the user.

Next, use a Precondition to say:

var: items_1 |GET| "user_id" = auth id

Here we use the GET filter with a default value of 0. This helps us account for existence of the record we want to edit. If the record does not exist, the precondition will trigger because a user_id value of 0 will not match the auth ID.

If the precondition passes, then the function stack will continue to run and edit the data. If it fails, it will throw an error and stop execution.

Last updated