Customer self-service
The central design problem in a customer portal is not the login page. It is establishing a trustworthy path from the logged-in user to the customer account and from that account to every record the user may see or change.
PHPRunner can generate the forms, lists, reports, and authentication around an existing database, but the ownership relationship must be designed before those pages are exposed to customers.
Quick answer: Build one enforced ownership chain: user → customer account → orders, invoices, documents, requests, and other business records. Derive the customer identity from the authenticated session, not from a customer ID supplied by the browser, and apply that rule to every route that can return or change data.
Authentication tells you who signed in; the account relationship determines which business data belongs to that person.
A portal commonly has a Users table, a Customers or Accounts table, and operational tables such as Orders, Invoices, Tickets, Projects, and Documents. A user record should map to an account through a stored relationship. Each customer-owned record then carries that account key directly or inherits it through a clearly defined parent record.
Do not trust a URL parameter, hidden form field, or submitted CustomerID to establish ownership. Those values come from the browser and can be changed. The application should obtain the current account from the authenticated user and use it when selecting, inserting, updating, exporting, or downloading records.
The distinction matters when one customer has several portal users.
If each login represents an individual consumer, a direct UserID on the business record may be sufficient. Business-to-business portals usually need an AccountID because several employees may work for the same customer. Their roles can differ—one person may submit requests, another may approve them, and a third may only view invoices—but they still share the same account boundary.
This also affects administration. Disabling one user should not disconnect the entire customer, while moving a user to another account should immediately change which records are visible.
A secure list page is not enough if another page bypasses the same rule.
| Portal path | Ownership rule |
|---|---|
| Lists and search | Return only records belonging to the current account. |
| View and edit pages | Verify both the record key and its account before loading or saving. |
| New records | Assign AccountID from the authenticated session rather than accepting it from the form. |
| Reports and exports | Use the same account filter as the interactive pages. |
| Files and downloads | Authorize the parent business record before returning the file. |
| APIs and custom actions | Repeat the server-side account check even when no normal page is displayed. |
The built-in security configuration handles the common case; events cover the exceptions.
Configure the login table and user permissions, then use PHPRunner's Advanced Security options to restrict users to records associated with their identity or account. Apply the same rule to master and detail tables that customers can reach.
Use server-side events for rules that are more specific than the standard ownership model—for example, assigning AccountID to a new request, permitting account administrators to see all company records, or preventing customers from changing internal workflow fields.
Draw the ownership chain before designing the portal screens.
Choose how users map to accounts, identify every table containing customer-owned data, and test every page, export, download, and custom action with two different customer accounts. The portal is ready only when changing an identifier cannot cross that boundary.