Konto i uwierzytelnianie¶
Założenie konta¶
Konto zakładasz jednym żądaniem — na hoście app.paragony.pl:
curl -s https://app.paragony.pl/account/accounts.json \
-H 'Content-Type: application/json' \
-d '{
"account": { "prefix": "moja-firma" },
"user": { "email": "integracje@mojafirma.pl",
"password": "TwojeSilneHaslo!",
"password_confirmation": "TwojeSilneHaslo!" }
}'
Odpowiedź 201 Created (najważniejsze pola):
{
"prefix": "moja-firma",
"product_app": "fiskator",
"user": {
"login": "integracje@mojafirma.pl",
"email": "integracje@mojafirma.pl",
"api_token": "intm..."
}
}
prefix— subdomena konta; od teraz całe API wołasz nahttps://moja-firma.paragony.pl.user.api_token— token API. Zapisz go od razu.- Konto można też założyć przez formularz na paragony.pl — wtedy token utworzysz później (patrz niżej).
Token API — skąd go wziąć¶
Surowy token jest zwracany wyłącznie w momencie utworzenia — przy rejestracji konta
(pole user.api_token powyżej) albo przy tworzeniu nowego tokena. Nie ma sposobu na
ponowne odczytanie: zgubiony token usuwasz i tworzysz nowy. Metadane istniejących tokenów
(bez sekretów) daje GET /account/api_tokens.json.
Nowy token utworzysz w interfejsie WWW konta (sekcja tokenów API) albo przez API —
POST /account/api_tokens.json, uwierzytelnione JWT-em
podpisanym dowolnym już posiadanym tokenem (np. tym z rejestracji konta):
curl -s https://moja-firma.paragony.pl/account/api_tokens.json \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type: application/json' \
-d '{ "api_token": { "name": "moj-system", "for_account": true } }'
Odpowiedź 201 zawiera pole token.
Utwórz token z for_account: true — nie jest przypisany do użytkownika i nie zostanie
usunięty z konta przy odpinaniu Twojego usera.
Uwierzytelnianie żądań — JWT¶
Przy każdym żądaniu generujesz krótkotrwały JWT podpisany swoim api_tokenem i wysyłasz go w standardowym nagłówku:
Authorization: Bearer <jwt>
Reguły budowy JWT:
- algorytm HS256; sekretem HMAC jest surowy token API;
- payload:
{ "key": "<fingerprint>", "exp": <unix timestamp> }, gdziekey= pierwsze 16 znaków hex z SHA-256 surowego tokena; exp— krótki czas życia (rekomendowane ~300 s);- segmenty JWT kodowane base64url bez paddingu (standardowy JWT).
Ruby (gem jwt)¶
require "jwt"
require "digest"
jwt = JWT.encode({ key: Digest::SHA256.hexdigest(api_token)[0, 16],
exp: Time.now.to_i + 300 }, api_token, "HS256")
# request["Authorization"] = "Bearer #{jwt}"
Node.js (pakiet jsonwebtoken)¶
import jwt from "jsonwebtoken";
import crypto from "node:crypto";
const key = crypto.createHash("sha256").update(apiToken).digest("hex").slice(0, 16);
const token = jwt.sign({ key }, apiToken, { algorithm: "HS256", expiresIn: 300 });
// headers.Authorization = `Bearer ${token}`;
curl¶
curl sam nie policzy JWT — wygeneruj go i podstaw:
JWT=$(ruby -rjwt -rdigest -e 't = ENV.fetch("PARAGONY_API_TOKEN")
puts JWT.encode({key: Digest::SHA256.hexdigest(t)[0,16], exp: Time.now.to_i + 300}, t, "HS256")')
curl -s "https://moja-firma.paragony.pl/printers.json" \
-H "Authorization: Bearer ${JWT}"
Wypróbuj bez pisania kodu¶
W referencji API wklej swój api_token w polu nad Swagger UI — JWT dla każdego
żądania „Try it out” zostanie policzony automatycznie w przeglądarce, zgodnie z regułami
budowy JWT opisanymi wyżej.
Warning
Nie wklejaj tam produkcyjnego api_token na współdzielonym albo publicznie dostępnym
komputerze. Token trafia wyłącznie do sessionStorage tej karty (znika po jej zamknięciu),
ale strona jest hostowana na publicznie osiągalnym portalu — każdy, kto ma dostęp do tej
samej przeglądarki przed zamknięciem karty, mógłby go odczytać z narzędzi deweloperskich.
Najczęstsze błędy uwierzytelnienia¶
| Objaw | Przyczyna |
|---|---|
401 {"error":"login_required"} |
brak nagłówka Authorization, format inny niż Bearer <jwt> albo JWT niepoprawny: zły podpis (inny sekret), złe key, wygasły exp, uszkodzona struktura. Odpowiedź nie niesie przyczyny — diagnozuj regułami budowy JWT wyżej |
| odpowiedź HTML zamiast JSON | żądanie poszło na paragony.pl albo złą subdomenę |