How an application connects to OpenPlatform: the launch and the verification
When a user opens an application, OpenPlatform does not send a password or a cookie to it. It sends a one-time launch address, and the application calls back to OpenPlatform to learn who the user is. This page follows the code (schemas/account.js, action Account/run, and controllers/verify.js).
1. The launch
When the user clicks an application, the portal calls the API run/{appid}. OpenPlatform:
- checks that the application is in the list of the user (
App not foundotherwise) and that it is not disabled; - creates a session of the application (table
tbl_app_session) that expires after the settingapp_session_expire(one day by default); - builds the verification address: the platform
url+/verify/?token=+ the identifier of the session joined to the identifier of the installation withX, followed byXand a checksum (FUNC.checksum, which uses the secretsaltchecksum); - derives the two tokens of that session from the shared secrets of the application:
reqtoken= the MD5 of the verification address salted with thereqtokenof the application, in lower case;restoken= the MD5 of thatreqtokensalted with therestokenof the application;
url with one extra query parameter: openplatform=<verification address>~<reqtoken>.For an application marked as a bookmark there is no handshake: the address gets ssid=<session checksum> instead.
2. The verification
The application takes the value of openplatform, which is the verification address, a ~ and the reqtoken of the session, and:
- computes its own
restoken: the MD5 of thereqtokensalted with therestokenthat it shares with OpenPlatform; - calls
GETon the whole value ofopenplatform(the~and thereqtokenstay in the query string) with the headerx-tokenset to thatrestoken.
OpenPlatform then (controllers/verify.js):
- splits the query token at the last
~(the part after it is thereqtokenthat it sent) and refuses the call when the header or the token is missing; - checks the checksum of the session identifier, reads the session and compares both secrets (
reqtokenand therestokenof the header); any difference isInvalid token; - if the application has a list of allowed addresses, checks the address of the caller (
Not allowed IP address); - reads the user and refuses a disabled user (
User has been disabled) or an inactive one (User is inactive); - makes sure the user has the notification links of this application (table
tbl_user_app); - builds the answer and passes it through the transformation
verifyof the platform, so a deployment can add fields.
The answer is a JSON object. Empty values are dropped from it. Its main fields are:
| Field | What it is |
|---|---|
id, name, email, photo, gender, reference | who the user is (photo is an absolute address) |
language, color, interface, darkmode, sounds | the preferences (the platform language and colour when the user has none) |
sa | the user is an administrator of the platform |
permissions | the value strings of the permissions of the user in this application |
groups | the ids of the groups of the user |
appid, ssid | the application and the checksum of its session |
openplatformid, openplatform | the identifier and the address of the installation |
iframe | true unless the application is external |
notify | the address to send notifications to, when the user accepts them (notifications) |
platform | the name and logo of the platform, its groups and the applications of the user |
The answer is kept in an in-memory cache keyed by the session token (the part before the ~) and the cache is cleared every two minutes. A call with a token that is in that cache is answered from it, before the secrets are compared again, so a repeated verification inside that time is cheap.
3. Asking again later
GET /session/ takes the ssid that the application received (it also accepts openplatformid, token and session as the name of the parameter), checks its checksum and returns the user (id, language, name, color, sa, isonline) while the session of the user has not expired.
What to remember when you build the application
- Never ship the shared secrets to the browser: only the server of the application needs them.
- Verify on the server and create your own session from the answer; the
openplatformparameter is for one launch. - Use the
permissionsof the answer, not a role that the browser sends. - Total.js 5 has a native client for this family of protocols: see OPENCLIENT.