Otázka na vývoj aplikace šahající na feed produktů

vývojáři-aplikací
url
xml-feed

#1

Ahoj vyvíjím aplikaci v mergadu, která bude získavat přes api URL adresy produktů z feedu. Pročítal jsme dokumentaci tak se chci zeptat jestli jsem to správně pochopil. Nejprve uživatel klikne a přes hook mi dá oprávnění abych mohl pracovat s jeho aplikací. Pak ale abych mohl přistupovat k api potřebuju offline oauth? Přes něj bych měl token se kterým bych se měl připojovat k api? Existuje nějaká ukázka již hotové aplikace, kde by byl tento postup vidět.

Lukáš


#2

Ahoj, chápeš to naprosto správně. Aplikace by měla pracovat v tzv. offline režimu, tedy bude vyžadovat OAuth2 refresh_token grant type. Máme ukázku aplikace, která pracuje v online režimu (authorization_code grant type), viz logbook, bohužel zatím nikde nemáme příklad aplikace, která používá refresh_token. Ale snad zvládneme kostru nebo ukázku takové aplikace do konce týdne někde vystavit (díky @michalwiglasz), dáme pak vědět.

Taky teď pracujeme na vylepšení dokumentace, tutoriálu apod., takže by snad začátkem příštího měsíce mohly být některé věci z dokumentace jasnější.


#3

Zkusím to stručně popsat:
Aplikace se načte uživateli v rozhraní Mergada přes iframe, jako první krok by měla aplikace přes OAuth požádat o online token, tj. přesměrovat uživatele na URL v dokumentaci:

https://app.mergado.com/oauth2/authorize/
?client_id=123
&redirect_uri=//appcloud.mergado.com/nekam/do/me/aplikace
&response_type=code
&grant_type=authorization_code

Ta stránka authorize udělá nějaká ověření a nakonec přesměruje prohlížeč na redirect_uri. Tam by aplikace měla udělat jen to, že na základě code, které dostane v URL pošle POST požadavek o token na https://app.mergado.com/oauth2/token/. Zpátky dostane JSON s tokenem a expirací, ten si uloží do session a přesměruje uživatele kamkoliv potřebuje (ideálně na stránku, kterou si původně otevřel, v Nette se hodí dvojice metod presenteru storeRequest a restoreRequest.

A to je celé, uživatel je autorizovaný, aplikace má validní access token. Pokud vyprší, lze toto kolečko zopakovat, ale já to dělám tak, že si požádám o offline token. Tam je to velmi jednoduché, stačí jeden GET, netřeba žádného přesměrování.

Používám tuto knihovnu: https://github.com/thephpleague/oauth2-client - ten příklad co tam mají je dobrý odrazový můstek. Zkusím ale nachystat nějaký kompletní příklad na míru Mergada, jak píše Pavel, pokud to tedy stihnu.


#4

Nicméně, pokud jde o nějaký úkol na pozadí spouštěný cronem, je správná cesta offline token - ostatně to ani neběží v prohlížeči, takže není co kam přesměrovávat. Na to stačí tenhle kousek kódu (využívá tu zmíněnou knihovnu):

<?php
use \League\OAuth2\Client\Provider\AbstractProvider;

class OfflineAuthenticator extends BaseOauthAuthenticator
{
    public function authenticate($storeRequestCallback = NULL)
    {
        if (!$this->entityId) {
            throw new \Exception("Entity ID must be set before authenticating.");
        }

        $this->token = $this->tokenStorage->getToken($this->entityId, ITokenStorage::OFFLINE);
        if (!$this->token) {
            $this->token = $this->oauthProvider->getAccessToken('refresh_token', [
                'refresh_token' => base64_encode($this->entityId),
            ]);
            $this->tokenStorage->storeToken($this->token, ITokenStorage::OFFLINE);
        }
    }

    public function refresh()
    {
        $this->token = NULL;
        $this->tokenStorage->deleteToken($this->entityId, ITokenStorage::OFFLINE);
        $this->authenticate();
    }

    public function getAuthenticatedRequest($method, $url, $params)
    {
        if (!$this->token) {
            throw new \Exception("Cannot create request: client not authenticated");
        }

        if ($this->token->hasExpired()) {
            $this->refresh();
        }

        return $this->oauthProvider->getAuthenticatedRequest($method, $url, $this->token, $params);
    }
}

Není to úplně kompletní příklad, ale je tam vše důležité.