Xano Documentation
  • 👋Welcome to Xano!
  • 🌟Frequently Asked Questions
  • 🔐Security & Compliance (Trust Center)
  • 🙏Feature Requests
  • 💔Known Issues
  • Before You Begin
    • Using These Docs
    • Where should I start?
    • Set Up a Free Xano Account
    • Key Concepts
    • The Development Life Cycle
    • Navigating Xano
    • Plans & Pricing
  • The Database
    • Designing your Database
    • Database Basics
      • Using the Xano Database
      • Field Types
      • Relationships
      • Database Views
      • Export and Sharing
      • Data Sources
    • Migrating your Data
      • Airtable to Xano
      • Supabase to Xano
      • CSV Import & Export
    • Database Performance and Maintenance
      • Storage
      • Indexing
      • Maintenance
      • Schema Versioning
  • 🛠️The Function Stack
    • Building with Visual Development
      • APIs
        • Swagger (OpenAPI Documentation)
      • Custom Functions
        • Async Functions
      • Background Tasks
      • Triggers
      • Middleware
      • Configuring Expressions
      • Working with Data
    • Functions
      • AI Tools
      • Database Requests
        • Query All Records
          • External Filtering Examples
        • Get Record
        • Add Record
        • Edit Record
        • Add or Edit Record
        • Patch Record
        • Delete Record
        • Bulk Operations
        • Database Transaction
        • External Database Query
        • Direct Database Query
        • Get Database Schema
      • Data Manipulation
        • Create Variable
        • Update Variable
        • Conditional
        • Switch
        • Loops
        • Math
        • Arrays
        • Objects
        • Text
      • Security
      • APIs & Lambdas
        • Realtime Functions
        • External API Request
        • Lambda Functions
      • Data Caching (Redis)
      • Custom Functions
      • Utility Functions
      • File Storage
      • Cloud Services
    • Filters
      • Manipulation
      • Math
      • Timestamp
      • Text
      • Array
      • Transform
      • Conversion
      • Comparison
      • Security
    • Data Types
      • Text
      • Expression
      • Array
      • Object
      • Integer
      • Decimal
      • Boolean
      • Timestamp
      • Null
    • Environment Variables
    • Additional Features
      • Response Caching
  • Testing and Debugging
    • Testing and Debugging Function Stacks
    • Unit Tests
    • Test Suites
  • CI/CD
  • File Storage
    • File Storage in Xano
    • Private File Storage
  • Realtime
    • Realtime in Xano
    • Channel Permissions
    • Realtime in Webflow
  • Maintenance, Monitoring, and Logging
    • Statement Explorer
    • Request History
    • Instance Dashboard
      • Memory Usage
  • Building Backend Features
    • User Authentication & User Data
      • Separating User Data
      • Restricting Access (RBAC)
      • OAuth (SSO)
    • Webhooks
    • Messaging
    • Emails
    • Custom Report Generation
    • Fuzzy Search
    • Chatbots
  • Xano Features
    • Snippets
    • Instance Settings
      • Release Track Preferences
      • Static IP (Outgoing)
      • Change Server Region
      • Direct Database Connector
      • Backup and Restore
      • Security Policy
    • Advanced Back-end Features
      • Xano Link
      • Developer API (Deprecated)
    • Metadata API
      • Master Metadata API
      • Tables and Schema
      • Content
      • Search
      • File
      • Request History
      • Workspace Import and Export
      • Token Scopes Reference
  • Xano AI
    • Building a Backend Using AI
    • Get Started Assistant
    • AI Database Assistant
    • AI Lambda Assistant
    • AI SQL Assistant
    • API Request Assistant
    • Template Engine
    • Streaming APIs
  • AI Tools
    • MCP Servers
      • Connecting Clients
      • MCP Functions
  • Xano Transform
    • Using Xano Transform
  • Xano Actions
    • What are Actions?
    • Browse Actions
  • Team Collaboration
    • Realtime Collaboration
    • Managing Team Members
    • Branching & Merging
    • Role-based Access Control (RBAC)
  • Agencies
    • Xano for Agencies
    • Agency Features
      • Agency Dashboard
      • Client Invite
      • Transfer Ownership
      • Agency Profile
      • Commission
      • Private Marketplace
  • Enterprise
    • Xano for Enterprise
    • Enterprise Features
      • Microservices
      • Tenant Center
      • Compliance Center
      • Security Policy
      • Instance Activity
      • Deployment
      • RBAC (Role-based Access Control)
      • Xano Link
  • Your Xano Account
    • Account Page
    • Billing
    • Referrals & Commissions
  • Troubleshooting & Support
    • Error Reference
    • Troubleshooting Performance
      • When a single workflow feels slow
      • When everything feels slow
      • RAM Usage
      • Function Stack Performance
    • Getting Help
      • Granting Access
      • Community Code of Conduct
      • Community Content Modification Policy
  • Special Pricing
    • Students & Education
    • Non-Profits
  • Security
    • Best Practices
Powered by GitBook
On this page

Was this helpful?

  1. Building Backend Features
  2. User Authentication & User Data

Separating User Data

Last updated 3 months ago

Was this helpful?

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.

(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

WHERE
db: items.user_id = auth id

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.

WHERE
auth id = var: user.id

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:

WHERE
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.

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

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

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 first by logging in or signing up.

authentication
Query All Records
authenticate
Restricting Access
Require authentication for the API endpoint.
Add an expression to the Query All Records function for items.
Filter the record where the user_id must be equal to the auth id.
Items only belonging to user 2 are returned.
Get the user record with the auth id.
Set a precondition where the ID of the user record is equal to the auth id.
First, Get the Record that the user is trying to edit.
The precondition enforces that the record belongs to the user trying to edit it. Using the GET filter makes sure that the record exists - if it doesn't the precondition will fail.