Przejdź do głównej zawartości

Uwierzytelnianie w API

Dla: Programista

Każde żądanie do API niesie klucz API integracji. Klucz identyfikuje integrację, a przez nią drukarnię, zakresy i limit żądań. Zapisy wykonane kluczem mają w Prynt autora: konto integracji.

Wysyłaj klucz w nagłówku Authorization ze schematem Bearer:

POST /api/v1/graphql HTTP/1.1
Host: twoja-drukarnia.prynt.pl
Authorization: Bearer prynt_…
Content-Type: application/json

Łącz się wyłącznie przez https://. Żądanie z kluczem wysłane zwykłym http:// nie działa: API odrzuca je błędem API_TOKEN_INSECURE_TRANSPORT, zanim sprawdzi klucz, albo przekierowuje je na https://. Klucz przeszedł już jednak przez sieć jawnym tekstem, więc traktuj go jak ujawniony: poproś o jego unieważnienie i wdróż nowy (zobacz Po wycieku klucza), także wtedy, gdy integracja po poprawce adresu znów działa. Klucz nie trafia do adresu URL, parametrów ani treści żądania. Żądanie z kluczem nigdy nie korzysta z sesji przeglądarki: ciasteczka są przy nim ignorowane.

API sprawdza klucz, zanim przeczyta zapytanie. Jeszcze wcześniej sprawdza, skąd przyszło żądanie: stronę spoza Prynt i połączenie przez http:// odrzuca bez sprawdzania klucza. Żądanie, którego nie przyjmie, dostaje odpowiedź bez data, nawet przy najprostszym zapytaniu:

Status subCode Co znaczy
403 ORIGIN_NOT_ALLOWED Żądanie ma nagłówek Origin strony spoza Prynt. Odrzucone przed sprawdzeniem klucza.
403 API_TOKEN_INSECURE_TRANSPORT Klucz przyszedł przez http://. Odrzucony bez sprawdzenia: traktuj go jak ujawniony i wymień.
401 API_TOKEN_INVALID, API_TOKEN_EXPIRED Klucz jest błędny, unieważniony albo wygasł.
403 API_INTEGRATION_NOT_APPROVED, API_INTEGRATION_SUSPENDED, API_TOKEN_BROWSER_USE Klucz jest poprawny, ale integracja nie ma akceptacji, jest wstrzymana albo żądanie wysłała przeglądarka.
429 brak (code: RATE_LIMITED) Limit żądań, zobacz Limity.
503 API_KEY_CHECK_UNAVAILABLE Prynt chwilowo nie może sprawdzić klucza. Ponów za chwilę.

Najprościej sprawdzisz klucz zapytaniem currentApiKey z Szybkiego startu: nie wymaga zakresu i zwraca integrację, zakresy oraz daty ważności klucza i akceptacji. Błąd 503 API_KEY_CHECK_UNAVAILABLE nie mówi nic o kluczu: nie wymieniaj go, tylko ponów żądanie.

Klucz zaczyna się od prynt_ i ma 55 znaków: po prefiksie są wyłącznie cyfry i litery łacińskie (base62), a ostatnie znaki to suma kontrolna. API odrzuca klucz z literówką, zanim go sprawdzi. W aplikacji klucz jest pokazywany skrótem z czterema ostatnimi znakami, np. prynt_…k3Fq.

Wyrażenie regularne, które znajduje klucz Prynt w dowolnym tekście:

\bprynt_[0-9A-Za-z]{49}\b

Zarejestruj je w skanerze sekretów, którego używasz: w GitHub (własny wzorzec skanowania sekretów), w filtrach logów albo w gitleaks:

.gitleaks.toml
[[rules]]
id = "prynt-api-key"
description = "Prynt API key"
regex = '''\bprynt_[0-9A-Za-z]{49}\b'''
keywords = ["prynt_"]
  • Tylko na serwerze. Klucz nie może trafić do przeglądarki, aplikacji mobilnej ani programu instalowanego u klienta. Operację wysłaną z nagłówkiem Origin (czyli przez przeglądarkę) API odrzuca błędem API_TOKEN_BROWSER_USE, nawet gdy klucz jest poprawny. Żądanie z nagłówkiem Origin strony spoza Prynt API odrzuca jeszcze wcześniej, zanim sprawdzi klucz, błędem ORIGIN_NOT_ALLOWED: przeglądarka pokaże wtedy błąd CORS. Program serwerowy nie wysyła nagłówka Origin, chyba że go dopiszesz.
  • W menedżerze sekretów albo zmiennej środowiskowej ustawianej przy wdrożeniu. Nigdy w kodzie, repozytorium, pliku konfiguracyjnym w repozytorium ani w zgłoszeniu.
  • Nie loguj klucza. Usuwaj nagłówek Authorization z logów żądań i raportów błędów.
  • Osobny klucz na środowisko. Środowisko testowe i produkcyjne Twojej integracji używają osobnych kluczy, nazwanych przy wydaniu np. „Sklep — serwer testowy” i „Sklep — serwer produkcyjny”, więc każdy z nich unieważnisz niezależnie. Gdy wersja testowa ma mieć mniej uprawnień, np. tylko odczyt, poproś drukarnię o osobną integrację z węższymi zakresami.
  • Testy działają na prawdziwych danych. Prynt nie ma osobnego środowiska testowego (sandboxa): każda integracja, także ta do testów, czyta i zapisuje prawdziwe dane drukarni. Zanim zaczniesz testować zapisy, uzgodnij z drukarnią, na których rekordach możesz pracować i jak je oznaczyć, np. nazwą zaczynającą się od „TEST”.

Każdy klucz ma ważność, którą administrator drukarni wybiera przy jego wydaniu: 30, 90, 180 albo 365 dni. Przed jej końcem administratorzy drukarni dostają przypomnienia (30, 7 i 1 dzień wcześniej). Po niej API odpowiada błędem API_TOKEN_EXPIRED. Zaplanuj rotację z wyprzedzeniem, żeby integracja nie stanęła. Datę ważności klucza i akceptacji integracji zwraca currentApiKey (expiresAt, approvalExpiresAt): integracja może ją sprawdzać sama, np. raz dziennie.

Integracja może mieć naraz dwa działające klucze, a rotacja na czas zakładki dokłada nowy klucz obok starego, więc klucz wymienisz bez przerwy w działaniu:

  1. Administrator drukarni klika Rotuj przy kluczu, w polu Stary klucz działa jeszcze przez wybiera 1 godzina, 1 dzień albo 7 dni, wpisuje Twoje hasło i klika Rotuj klucz. Dostaje nowy klucz z taką samą ważnością jak stary (np. 180 dni), liczoną od dnia rotacji. Stary klucz ma w aplikacji status Wygasa po rotacji.

  2. Wdróż nowy klucz w integracji i sprawdź, że żądania przechodzą.

  3. Gdy cała integracja korzysta z nowego klucza, stary przestaje działać sam po okresie zakładki. Administrator może go też unieważnić wcześniej.

Unieważnij w aplikacji wyłącza klucz od razu i na stałe. Kolejne żądania z nim dostają błąd API_TOKEN_INVALID: API celowo nie odróżnia klucza unieważnionego od nieistniejącego.

Klucz, który mógł zobaczyć ktoś niepowołany (repozytorium, log, zrzut ekranu, przeglądarka, połączenie przez http://), traktuj jak ujawniony:

  1. Poproś administratora drukarni o natychmiastowe Unieważnij przy tym kluczu.

  2. Wydajcie nowy klucz i wdróż go w integracji.

  3. Sprawdźcie w Prynt historię zmian rekordów, których integracja dotyka (zamówień, klientów, magazynu), od chwili wycieku. Każdy zapis kluczem ma integrację jako autora, z plakietką Integracja.

  4. Usuń klucz z miejsca wycieku. W repozytorium nie wystarczy nowy commit: klucz zostaje w historii, dlatego najpierw go unieważnij.

  5. Jeśli widzicie zapisy, których integracja nie wykonała, napiszcie na [email protected]. Nie dołączajcie klucza.