Balíkonoš OAuth 2.0 autorizace

Pro testování využívejte výhradně testovací prostředí na doméně https://test.balikonos.cz!

Základní informace

OAuth 2.0 protokol, sloužící k autorizaci API klientů, byl na našem webu vytvořen dle oficiální specifikace RFC 6749. Popis samotného protokolu je zde uveden pouze okrajově. Pro detaily konkrétních částí protokolu doporučujeme pročíst odkazované části specifikace. Vysvětlení základního principu tohoto protokolu lze nalézt také zde. Vyzkoušet si tento protokol můžete na Google OAuth 2.0 Playground. Konkrétní detaily implementace naleznete níže.

Postup

Pro přístup ke zdrojům využijte takzvaný authorization_code grant (viz specifikace). Je nutné dodržet následující postup:

  1. Zaregistrujte OAuth 2.0 klienta (vaše aplikace využívající naše API) ve formuláři na našem webu
  2. Zažádejte o authorization code (přesměrováním či nasměrováním na autorizační endpoint v naší aplikaci)
    1. V naší aplikaci se registrovaná společnost přihlásí a povolí či zamítne přístup Vaší aplikace
    2. Po tomto rozhodnutí dojde k přesměrování na předem zaregistrované redirect_uri na Vaší aplikaci
    3. V případě povolení přístupu získáte authorization_code, který v následujícím kroku "vyměníte" za access_token a refresh_token
  3. Na token endpointu zažádejte o access token pomocí authorization_code a dalších údajů
  4. Přístupujte ke zdrojům pomocí access_tokenu po dobu jeho platnosti
  5. Po vypršení platnosti access_tokenu si pomocí refresh_tokenu vyžádejte nový

Tento postup je popsán ve specifikaci v sekci 4.1 Implicit grant ani další granty nejsou podporovány s výjimknou refresh tokenu.


I nadále se použití označení "klient" shoduje s tím jak je definován ve specifikaci. Označujte tedy OAuth klienta (Vaší aplikaci).

Registrace klienta

K registraci slouží formulář, který požaduje základní údaje o Vaší firmě. Tedy firmě či aplikaci využívající API a přistupující k údajům společnosti či společností registrovaných v Balíkonoši. Nejdůležitějším údajem v tomto formuláři je adresa pro přesměrování (ve specifikaci jde o redirect_uri). Ta definuje endpoint, na který budou přesměrovávány všechny požadavky z naší aplikace. Tato adresa by měla mít protokol https.

Heslo je váš autentizační údaj, ve specifikaci vedený jako client_secret. Toto heslo se využívá při žádostech o access_token jako heslo v HTTP Basic autentizaci. Jako přihlašovací jméno v této HTTP Basic autentizaci je použit vygenerovaný identifikátor, který získáte při dokončení registrace. Ve specifikaci je tento údaj vedený jako client_id. Tato implementace nepodporuje přihlášení pomocí údajů v query parametrech či v těle požadavku. Ukázka požadavku s touto autentizací je uvedena níže.

Aktuálně nejsou podporování public klienti (obvykle implementovaní v JavaScriptu).

Žádost o authorization code

Authorization Endpoint je umístěn na adrese https://balikonos.cz/connect/authorize/. Kromě povinných query parametrů dle specifikace (response_type a client_id) vyžaduje tato implementace i scope a state. Scope jednotlivých zdrojů je definován v dokumentaci zdrojů. Je nutné, aby Váš klient ověřoval shodu state query parametru v odpovědi z našeho serveru s Vámi odeslanou náhodnou hodnotou tohoto parametru. Tímto ověřením se předchází CSRF útokům.

V případě, že uvedete i parametr redirect_uri, je nutné, aby se přesně shodoval s adresou uvedenou při registraci Vašeho klienta.

Při úspěšném požadavku je uživateli zobrazen formulář s možností povolit či zamítnout přístup Vaší aplikace k jeho údajům. Spolu s tím je zobrazen název Vaší společnosti, logo, webová adresa, žádaný scope a adresa, na kterou bude přesměrován.

V případě povolení přístupu od uživatele získáte authorization_code s platností 90 vteřin. Tento kód má vždy délku 40 znaků a obsahuje pouze malá písmena nebo čísla.


Příklad požadavku:

Detailní popis požadavku najdete ve specifikaci.

GET /connect/authorize/?client_id=v360me17yf&response_type=code&scope=deliveries+collection-protocols&state=csjkhd5b1 HTTP/1.1 Host: balikonos.cz
Příklad odpovědi (po schválení a přesměrování na Vaší aplikaci):

Detailní popis odpovědi najdete ve specifikaci.

GET /redirect_uri/?code=f76f86b775cd3d70698d14462b8067705ea83b52&state=csjkhd5b1 HTTP/1.1 Host: client.tld
Příklad odpovědi (po zamítnutí a přesměrování na Vaší aplikaci):

Seznam všech možných chybových odpovědí najdete ve specifikaci.

GET /redirect_uri/?error=access_denied&error_description=The+user+denied+access+to+your+application&state=csjkhd5b1 HTTP/1.1 Host: client.tld

Žádost o access token

Token Endpoint je umístěn na adrese https://balikonos.cz/connect/token/. Tato adresa slouží k žádostem o access_token pomocí authorization_code i refresh_token.

Žádost pomocí authorization code:

Je nutné použít všechny povinné parametry dle specifikace. Hlavička POST požadavku musí obsahovat:

  • Authorization - HTTP Basic autentizace vaší aplikace "Basic ".base64_encode($client_id.":".$client_secret)
  • Content-type - přesná hodnota application/x-www-form-urlencoded

Tělo POST požadavku musí obsahovat hodnoty ve formátu application/x-www-form-urlencoded. Při získávání access_tokenu pomocí authorization_code je nutné vyplnit:

  • code - autorizační kód získaný v předešlé odpovědi
  • redirect_uri - zaregistrovaná adresa pro přesměrování
  • scope - seznam požadovaných přístupů oddělených mezerou (každý zdroj má svůj scope, více v seznamu zdrojů)
  • grant_type - musí být přesně authorization_code


Příklad požadavku o access token:

Detailní popis požadavku najdete ve specifikaci.

POST /connect/token/ HTTP/1.1 Host: balikonos.cz Authorization: Basic djM2MG1lMTd5ZjpoZXNsbw== Content-type: application/x-www-form-urlencoded code=f76f86b775cd3d70698d14462b8067705ea83b52 &redirect_uri=https://client.tld/redirect_uri/ &scope=deliveries+collection-protocols &grant_type=authorization_code
Příklad odpovědi s access tokenem:

Detailní popis odpovědi najdete ve specifikaci.

HTTP/1.1 200 OK Content-Type: application/json { "access_token": "fa6486007ade49ff27597cb9991a0fa4c26413df", "expires_in": 3600, "token_type": "bearer", "scope": "deliveries collection-protocols", "refresh_token": "a9b6062d72926917188ee95f4d6c4641c77624ad" }

Vrácený access_token má platnost 60 minut (je obsaženo i v odpovědi v sekundách) a refresh_token má neomezenou platnost. Oba tokeny mají vždy délku 40 znaků a obsahují pouze malá písmena nebo čísla. Při získávání nových access tokenů pomocí refresh tokenu získáte stejnou strukturu bez položky refresh_token. V případě, že uživatel zpětně zamítne přístup Vaší aplikace k jeho údajům, jsou odstraněny všechny Vaše tokeny přidružené k tomuto uživateli.



Žádost pomocí refresh token:

Po expiraci starého access_token zažádejte o nový pomocí refresh_token. Hlavička tohoto POST požadavku musí obsahovat totožné údaje jako v případě žádosti pomocí authorization_code. V těle požadavku je nutné vyplnit:

  • refresh_token - refresh token získaný v prvotním požadavku
  • redirect_uri - zaregistrovaná adresa pro přesměrování
  • scope - seznam požadovaných přístupů oddělených mezerou
  • grant_type - musí být přesně refresh_token

Příklad požadavku s refresh tokenem:
POST /connect/token/ HTTP/1.1 Host: balikonos.cz Authorization: Basic djM2MG1lMTd5ZjpoZXNsbw== Content-type: application/x-www-form-urlencoded refresh_token=a9b6062d72926917188ee95f4d6c4641c77624ad &redirect_uri=https://client.tld/redirect_uri/ &scope=deliveries+collection-protocols &grant_type=refresh_token
Příklad odpovědi:
HTTP/1.1 200 OK Content-Type: application/json { "access_token": "bacffecfc1bd349b85e51b37a542aed57f457a8e", "expires_in": 3600, "token_type": "bearer", "scope": "deliveries collection-protocols" }

Přístup ke zdrojům

Všechny přístupy ke zdrojům vyžadují HTTP Bearer autentizaci specifikovanou v RFC 6750. Použijte tedy access_token v HTTP hlavičce Authorization. Přihlašování pomocí tokenu v query parametru nebo v těle požadavku není podporován.


Příklad požadavku
GET /api/v1/deliveries?deliveryId=10000 HTTP/1.1 Host: balikonos.cz Authorization: Bearer bacffecfc1bd349b85e51b37a542aed57f457a8e Accept: application/json
Expirace access tokenu

Je nutné ve Vaší aplikaci kontrolovat, zda používáte platný access token (v době jeho platnosti). Pokud dojde k požadavku s expirovaným či jinak neplatným tokenem, je vrácena chyba dle specifikace. Pro expirovaný token je vrácena následující odpověď:

HTTP/1.1 401 Authorization required WWW-Authenticate: Bearer realm="ClientApi", error="invalid_token", error_description="The access token provided has expired" Content-Type: application/json; charset=UTF-8 { "code": 401, "status": "error", "message": "The access token provided has expired" }

Implementace klienstké části OAuth 2.0 protokolu

Přístup z vlastní aplikace

Pokud se plánujete připojovat k API pouze z vlastní aplikace, není nutné implementovat proces získání autorizačního kódu a jeho výměnu za refresh token. Tuto inicializační část lze udělat ručně a ve vlastní aplikaci již naprogramovat pouze získávání a používání nových access tokenů. K tomuto prvotnímu kroku dobře poslouží již zmíněný doplněk prohlížeče Chrome: POSTman. Samotný postup je jen několik málo manuálních kroků:

  1. Zaregistrovat svou aplikaci ve formuláři
  2. Přistoupit na adresu autorizačního endpointu s požadovanými scopes
  3. Přihlásit se do systému Balíkonoše
  4. Povolit přístup Vaší aplikaci
  5. Odeslat POST požadavek (například pomocí POSTmana) na token endpoint se získaným kódem a všemi ostatními potřebnými údaji
  6. Uložit si získaný refresh token

Je zřejmé, že pokud Vaše aplikace implementuje API pro více společností v Balíkonoši, je kompletní proces OAuth 2.0 protokolu naprostou nutností.

Ukládání tokenů

Vzhledem ke krátkodobé platnosti access tokenu (a nutnému získávání stále nových tokenů pomocí refresh tokenu) je vhodné uložit refresh token do databáze (pokud vytváříte aplikaci pro více společností registrovaných v systému Balíkonoš.cz) či do konfigurace aplikace (pokud vytváříte vlastní aplikaci pouze pro Vás).

Samotný access token lze uložit do session s platností daného tokenu a snížit tak overhead potřebný pro přístup ke zdrojům této API. Není tedy nutné ukládat access token do databáze. Zároveň je velmi nevhodné si vyžádat nový access token pro každý přístup ke zdrojům!

Ukázka komunikace

Uživatel přijde na náš Authorization Endpoint:

Po přihlášení se uživateli zobrazí možnost potvrdit či zamítnout žádost Vaší aplikace o přístup.

GET /connect/authorize/?client_id=v360me17yf&response_type=code&scope=deliveries+collection-protocols&state=csjkhd5b1 HTTP/1.1 Host: balikonos.cz
Přesměrování z naší aplikace na Vámi zaregistrovaný redirect_uri

Po schválení uživatelem získáte autorizačním kód a totožný state query parametr jako byl ve vašem požadavku.

GET /redirect_uri/?code=f76f86b775cd3d70698d14462b8067705ea83b52&state=csjkhd5b1 HTTP/1.1 Host: client.tld
Vyžádání prvního access tokenu z Vaší aplikace

Odřádkování je v těle odpovědi jen pro přehlednost. Všimněte si HTTP Basic autentizace klienta id v360me17yf a heslem heslo.

POST /connect/token/ HTTP/1.1 Host: balikonos.cz Authorization: Basic djM2MG1lMTd5ZjpoZXNsbw== Content-type: application/x-www-form-urlencoded code=f76f86b775cd3d70698d14462b8067705ea83b52 &redirect_uri=https://client.tld/redirect_uri/ &scope=deliveries+collection-protocols &grant_type=authorization_code HTTP/1.1 200 OK Content-Type: application/json { "access_token": "fa6486007ade49ff27597cb9991a0fa4c26413df", "expires_in": 3600, "token_type": "bearer", "scope": "deliveries collection-protocols", "refresh_token": "a9b6062d72926917188ee95f4d6c4641c77624ad" }
Vyžádánání access tokenu pomocí refresh tokenu

Odřádkování je v těle odpovědi jen pro přehlednost.

POST /connect/token/ HTTP/1.1 Host: balikonos.cz Authorization: Basic djM2MG1lMTd5ZjpoZXNsbw== Content-type: application/x-www-form-urlencoded refresh_token=a9b6062d72926917188ee95f4d6c4641c77624ad &redirect_uri=https://client.tld/redirect_uri/ &scope=deliveries+collection-protocols &grant_type=refresh_token HTTP/1.1 200 OK Content-Type: application/json { "access_token": "bacffecfc1bd349b85e51b37a542aed57f457a8e", "expires_in": 3600, "token_type": "bearer", "scope": "deliveries collection-protocols" }
Přístup ke zdrojům

Detaily možných odpovědí najdete v přímo v dokumentaci zdrojů.

GET /api/v1/deliveries?deliveryId=10000 HTTP/1.1 Host: balikonos.cz Authorization: Bearer bacffecfc1bd349b85e51b37a542aed57f457a8e Accept: application/json HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 { ... }