# Jak aplikacja łączy się z OpenPlatform: uruchomienie i weryfikacja

> Dokładny uścisk dłoni między OpenPlatform a aplikacją: adres, z którym jest otwierana, jak aplikacja podpisuje żądanie do /verify/ i dane użytkownika, które otrzymuje.

Framework: openplatform
Product: OpenPlatform (openplatform@5)
Language: pl
Content-SHA256: 9a52b0ff04460516752fa33ac6b259233719fa0f73d1942f88522b7b9b2831fc
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: 
Review: not-recorded

Gdy użytkownik otwiera aplikację, OpenPlatform nie wysyła jej hasła ani cookie. Wysyła **jednorazowy adres uruchomienia**, a aplikacja oddzwania do OpenPlatform, aby dowiedzieć się, kim jest użytkownik. Ta strona podąża za kodem (`schemas/account.js`, akcja `Account/run` i `controllers/verify.js`).

## 1. Uruchomienie

Gdy użytkownik kliknie aplikację, portal wywołuje API `run/{appid}`. OpenPlatform:

1. sprawdza, czy aplikacja jest na liście użytkownika (w przeciwnym razie `App not found`) i czy nie jest wyłączona;
2. tworzy sesję aplikacji (tabela `tbl_app_session`), która wygasa według ustawienia `app_session_expire` (domyślnie jeden dzień);
3. buduje **adres weryfikacji**: `url` platformy + `/verify/?token=` + identyfikator sesji połączony z identyfikatorem instalacji przez `X`, a po nim `X` i suma kontrolna (`FUNC.checksum`, która używa sekretu `saltchecksum`);
4. wyprowadza dwa tokeny tej sesji ze wspólnych sekretów aplikacji:
   - `reqtoken` = MD5 adresu weryfikacji z solą `reqtoken` aplikacji, małymi literami;
   - `restoken` = MD5 tego `reqtoken` z solą `restoken` aplikacji;
5. otwiera aplikację pod jej `url` z jednym dodatkowym parametrem zapytania: `openplatform=<verification address>~<reqtoken>`.

Dla aplikacji oznaczonej jako zakładka nie ma uścisku dłoni: adres otrzymuje zamiast tego `ssid=<session checksum>`.

## 2. Weryfikacja

Aplikacja bierze wartość `openplatform`, czyli adres weryfikacji, znak `~` i `reqtoken` sesji, i:

1. oblicza **własny** `restoken`: MD5 z `reqtoken` z solą `restoken`, który dzieli z OpenPlatform;
2. wywołuje `GET` na całej wartości `openplatform` (`~` i `reqtoken` zostają w query string) z nagłówkiem `x-token` ustawionym na ten `restoken`.

OpenPlatform następnie (`controllers/verify.js`):

1. dzieli token zapytania na ostatnim `~` (część po nim to `reqtoken`, który wysłał) i odrzuca wywołanie, gdy brakuje nagłówka lub tokenu;
2. sprawdza sumę kontrolną identyfikatora sesji, odczytuje sesję i porównuje oba sekrety (`reqtoken` i `restoken` z nagłówka); każda różnica to `Invalid token`;
3. jeśli aplikacja ma listę dozwolonych adresów, sprawdza adres wywołującego (`Not allowed IP address`);
4. odczytuje użytkownika i odrzuca wyłączonego (`User has been disabled`) lub nieaktywnego (`User is inactive`);
5. upewnia się, że użytkownik ma odnośniki powiadomień tej aplikacji (tabela `tbl_user_app`);
6. buduje odpowiedź i przepuszcza ją przez transformację `verify` platformy, aby wdrożenie mogło dodać pola.

Odpowiedź to obiekt JSON. Puste wartości są z niego usuwane. Jego główne pola to:

| Pole | Co to jest |
|---|---|
| `id`, `name`, `email`, `photo`, `gender`, `reference` | kim jest użytkownik (`photo` to adres bezwzględny) |
| `language`, `color`, `interface`, `darkmode`, `sounds` | preferencje (język i kolor platformy, gdy użytkownik ich nie ma) |
| `sa` | użytkownik jest administratorem platformy |
| `permissions` | ciągi `value` uprawnień użytkownika w tej aplikacji |
| `groups` | identyfikatory grup użytkownika |
| `appid`, `ssid` | aplikacja i suma kontrolna jej sesji |
| `openplatformid`, `openplatform` | identyfikator i adres instalacji |
| `iframe` | `true`, chyba że aplikacja jest zewnętrzna |
| `notify` | adres, na który wysyłać powiadomienia, gdy użytkownik je akceptuje ([powiadomienia](/en/openplatform/notifications-and-public-api/)) |
| `platform` | `name` i `logo` platformy, jej `groups` i aplikacje użytkownika |

Odpowiedź jest przechowywana w pamięci podręcznej w pamięci operacyjnej z kluczem w postaci tokenu sesji (część przed `~`), a pamięć jest czyszczona co dwie minuty. Wywołanie z tokenem, który jest w tej pamięci, otrzymuje odpowiedź z niej, zanim sekrety zostaną ponownie porównane, więc powtórna weryfikacja w tym czasie jest tania.

## 3. Ponowne zapytanie później

`GET /session/` przyjmuje `ssid`, który otrzymała aplikacja (jako nazwę parametru akceptuje też `openplatformid`, `token` i `session`), sprawdza jego sumę kontrolną i zwraca użytkownika (`id`, `language`, `name`, `color`, `sa`, `isonline`), dopóki sesja użytkownika nie wygasła.

## O czym pamiętać, budując aplikację

- Nigdy nie wysyłaj wspólnych sekretów do przeglądarki: potrzebuje ich tylko serwer aplikacji.
- Weryfikuj na **serwerze** i utwórz własną sesję z odpowiedzi; parametr `openplatform` jest na jedno uruchomienie.
- Używaj `permissions` z odpowiedzi, a nie roli wysłanej przez przeglądarkę.
- Total.js 5 ma natywnego klienta dla tej rodziny protokołów: zobacz [OPENCLIENT](/en/total5/openclient-protocol/).
