Autorizarea

Descriere - Autorizare

  • Pentru accesarea API-urilor Keez este necesara obtinerea unui token de acces (bearer token) folosind fluxul OAuth 2.0 client credentials

  • Data fiind faptul ca aplicatia permite asocierea unui cont la mai multi clienti, apelurile catre API necesita in general si specificarea unui clientEid, un identificator al clientului si un secret, de asemenea furnizat de Keez.

Medii

  • Aplicatia keez.ro pune la dispozitie 2 medii complet separate unde se vor realiza operatiile specifice acestul API:
    Staging
    • Este un mediu dedicat testarii API -ului de facturare. Orice factura realizata in acest mediu nu are impact contabil

    Atenționare

    Acest mediu la intervale semi-regulate este re-scris. Adica toate datele (facturi, articole) vor fi sterse complet fara posibilitate de recuparare de nici-un fel

    Productie sau App
    • Este mediul de productie. Orice factura realizata in acest mediu va impacta direct contabilitatea clientului

    Atenționare

    Acest mediu nu este niciodata re-scris. Orice articol/factura realizata in acest mediu va ramane permanent stocata in baza de date

Atenționare

Mediile stage si prod sunt complet separate din toate punctele de vedere: locatie server, aplicatie online, baza de date, apel operatii API. Orice adaugare/modificare/stergere pe un mediu nu-l va impacta pe celalalt

Proprietati

Atenționare

Pentru procurarea urmatoarelor proprietati necesare, va rugam sa contactati firma Keez.ro!

Proprietati necesare la apelul API-ului pentru obtinerea token-ului de autorizare:
client_eid
  • este un identificator extern pentru compania care foloseste API -ul;

  • fiecare client primeste un identificator unic;

  • este oferit de cate un reprezentat https://keez.ro/

application_id
  • este un identificator al aplicatiei care va rula operatiile API -ului

  • poate fi considerat ca fi un „username”

  • este oferit de cate un reprezentat https://keez.ro/

secret

Notă

Pentru a intelege mai bine aceste proprietati, daca am extrapola acest API la o pagina de login din zilele noastre, acestea ar putea fi definite ca:

  • client_eid = name

  • application_id = user

  • secret = password

Preluarea unui token

  • Preluarea unui token se realizeaza prin operatia de POST

  • URL -ul de acces token este: https://{MEDIU}.keez.ro/idp/connect/token

  • De observat proprietatea {MEDIU} din URL, aceasta se va inlocui cu MEDIU pentru care se face apelul:

  • Proprietatiile de mai sus (client_eid, application_id, secret) vor fi servite catre API sub forma de corp (body)

  • Rezultatul API -ului este de tip JSON din care se vor extrage cele necesare: Vezi Model Autorizare

  • Token-ul are un termen de expirare de 5 minute. Pentru folosirea API -ului este recomandata realizarea unei metode recursive de apel al preluarii token -ului. Vezi: Exemple Autorizare

Atenționare

De remarcat particularitatea «app» adaugata pentru „client_id” in fata parametrului „application_id”. Vezi exemplu

Exemple Autorizare

Preluare Token varianta simpla fara reimprospatare token (refresh after expire):
  • Metoda aceasta se foloseste atunci cand se realizeaza o operatie punctuala, cu durata scurta.

import requests

class TokenService:
    def __init__(self):
        self.token_url = 'https://staging.keez.ro/idp/connect/token'

        self.client_eid = '{RECEIVED_CLIENT_EID}'
        self.application_id = '{RECEIVED_APPLICATION_ID}'
        self.secret = '{RECEIVED_SECRET}'

    def generate_token(self):
        req = requests.post(self.token_url, data={
            'client_id': f'app{self.application_id}',
            'client_secret': self.secret,
            'grant_type': 'client_credentials',
            "scope": "public-api",
        }, headers={
            'Content-Type': 'application/x-www-form-urlencoded'
        })
        req.raise_for_status()
        return req.json()


if __name__ == '__main__':
    token = TokenService()
    auth_token = token.generate_token()
    print(auth_token)
Preluare Token varianta complexa cu expirare token si refresh de token automat:
  • Este cea mai sigura metoda, pentru ca se bazeaza direct pe timpul de expirare al token-ului

  • De fiecare data cand token-ul expira, acesta se reimprospateaza

import time
import requests
import python_jwt as jwt


class TokenService:
    def __init__(self):
        self.token_url = 'https://staging.keez.ro/idp/connect/token'

        self.client_eid = '{RECEIVED_CLIENT_EID}'
        self.application_id = '{RECEIVED_APPLICATION_ID}'
        self.secret = '{RECEIVED_SECRET}'

        self.expires = None
        self.token = None
        self.expires = time.gmtime(0)

    def refresh_auth_token(self):
        if self.token_expired():
            self.generate_token()

    def token_expired(self):
        return self.expires < time.gmtime()

    def generate_token(self):
        req = requests.post(self.token_url, data={
            'client_id': f'app{self.application_id}',
            'client_secret': self.secret,
            'grant_type': 'client_credentials',
            "scope": "public-api",
        }, headers={
            'Content-Type': 'application/x-www-form-urlencoded'
        })
        req.raise_for_status()
        json = req.json()

        self.token = f'{json["token_type"]} {json["access_token"]}'
        (_, claims) = jwt.process_jwt(json["access_token"])
        self.expires = time.gmtime(claims['exp'])

        return


if __name__ == '__main__':
    token = TokenService()
    token.refresh_auth_token()