# Cum se conectează o aplicație la OpenPlatform: lansarea și verificarea

> Strângerea de mână exactă dintre OpenPlatform și o aplicație: adresa cu care este deschisă, cum își semnează aplicația cererea către /verify/ și datele utilizatorului pe care le primește.

Framework: openplatform
Product: OpenPlatform (openplatform@5)
Language: ro
Content-SHA256: 66353fca48af9ac8d9824292bc71101d017fc207c8f73987cb18f6b194784825
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: 
Review: not-recorded

Când un utilizator deschide o aplicație, OpenPlatform nu îi trimite o parolă sau un cookie. Îi trimite o **adresă de lansare de unică folosință**, iar aplicația apelează înapoi OpenPlatform pentru a afla cine este utilizatorul. Această pagină urmează codul (`schemas/account.js`, acțiunea `Account/run` și `controllers/verify.js`).

## 1. Lansarea

Când utilizatorul face clic pe o aplicație, portalul apelează API-ul `run/{appid}`. OpenPlatform:

1. verifică dacă aplicația este în lista utilizatorului (altfel `App not found`) și dacă nu este dezactivată;
2. creează o sesiune a aplicației (tabelul `tbl_app_session`) care expiră după setarea `app_session_expire` (o zi implicit);
3. construiește **adresa de verificare**: `url` al platformei + `/verify/?token=` + identificatorul sesiunii unit cu identificatorul instalației prin `X`, urmat de `X` și o sumă de control (`FUNC.checksum`, care folosește secretul `saltchecksum`);
4. derivă cele două token-uri ale acelei sesiuni din secretele partajate ale aplicației:
   - `reqtoken` = MD5 al adresei de verificare cu sare `reqtoken` al aplicației, cu litere mici;
   - `restoken` = MD5 al acelui `reqtoken` cu sare `restoken` al aplicației;
5. deschide aplicația la `url` cu un parametru de interogare în plus: `openplatform=<verification address>~<reqtoken>`.

Pentru o aplicație marcată ca semn de carte nu există strângere de mână: adresa primește în schimb `ssid=<session checksum>`.

## 2. Verificarea

Aplicația ia valoarea `openplatform`, care este adresa de verificare, un `~` și `reqtoken` al sesiunii, și:

1. calculează **propriul** `restoken`: MD5 al `reqtoken` cu sare `restoken` pe care îl partajează cu OpenPlatform;
2. apelează cu `GET` întreaga valoare `openplatform` (`~` și `reqtoken` rămân în query string) cu antetul `x-token` setat la acel `restoken`.

OpenPlatform apoi (`controllers/verify.js`):

1. împarte token-ul interogării la ultimul `~` (partea de după este `reqtoken` pe care l-a trimis) și refuză apelul când lipsește antetul sau token-ul;
2. verifică suma de control a identificatorului de sesiune, citește sesiunea și compară ambele secrete (`reqtoken` și `restoken` din antet); orice diferență este `Invalid token`;
3. dacă aplicația are o listă de adrese permise, verifică adresa apelantului (`Not allowed IP address`);
4. citește utilizatorul și refuză un utilizator dezactivat (`User has been disabled`) sau inactiv (`User is inactive`);
5. se asigură că utilizatorul are linkurile de notificare ale acestei aplicații (tabelul `tbl_user_app`);
6. construiește răspunsul și îl trece prin transformarea `verify` a platformei, astfel încât o implementare să poată adăuga câmpuri.

Răspunsul este un obiect JSON. Valorile goale sunt eliminate din el. Câmpurile lui principale sunt:

| Câmp | Ce este |
|---|---|
| `id`, `name`, `email`, `photo`, `gender`, `reference` | cine este utilizatorul (`photo` este o adresă absolută) |
| `language`, `color`, `interface`, `darkmode`, `sounds` | preferințele (limba și culoarea platformei când utilizatorul nu are) |
| `sa` | utilizatorul este administrator al platformei |
| `permissions` | șirurile `value` ale permisiunilor utilizatorului în această aplicație |
| `groups` | id-urile grupurilor utilizatorului |
| `appid`, `ssid` | aplicația și suma de control a sesiunii ei |
| `openplatformid`, `openplatform` | identificatorul și adresa instalației |
| `iframe` | `true` cu excepția cazului în care aplicația este externă |
| `notify` | adresa la care se trimit notificările, când utilizatorul le acceptă ([notificări](/en/openplatform/notifications-and-public-api/)) |
| `platform` | `name` și `logo` ale platformei, `groups` ale ei și aplicațiile utilizatorului |

Răspunsul este păstrat într-un cache în memorie având drept cheie token-ul sesiunii (partea dinaintea lui `~`), iar cache-ul este golit la fiecare două minute. Un apel cu un token aflat în acel cache primește răspunsul din el, înainte ca secretele să fie comparate din nou; o verificare repetată în acel interval este deci ieftină.

## 3. Întrebarea din nou, mai târziu

`GET /session/` primește `ssid` pe care l-a primit aplicația (acceptă și `openplatformid`, `token` și `session` ca nume al parametrului), îi verifică suma de control și returnează utilizatorul (`id`, `language`, `name`, `color`, `sa`, `isonline`) cât timp sesiunea utilizatorului nu a expirat.

## Ce să ții minte când construiești aplicația

- Nu trimite niciodată secretele partajate către browser: doar serverul aplicației are nevoie de ele.
- Verifică pe **server** și creează-ți propria sesiune din răspuns; parametrul `openplatform` este pentru o singură lansare.
- Folosește `permissions` din răspuns, nu un rol trimis de browser.
- Total.js 5 are un client nativ pentru această familie de protocoale: vezi [OPENCLIENT](/en/total5/openclient-protocol/).
