top of page

API Autentizace v Power Query

  • Writer: Vojtěch Šíma
    Vojtěch Šíma
  • Nov 30, 2024
  • 8 min read

Updated: Feb 17


tl;dr když pracujete s API v Power Query, je důležité znát několik autentizačních metod: Anonymous, API Key, Bearer Token, Basic a OAuth 2.0. Většina z těchto metod vyžaduje autorizační hlavičku v rámci funkce Web.Contents(). V tomto článku se dozvíte, jak zvládnout všech těchto pět metod. Existují i další, méně časté metody (v Power Query), o kterých nebudeme podrobně mluvit, ale připojil jsem odkaz, pokud byste se o nich chtěli dozvědět více.

Autentizace vs. Autorizace

Už jste se určitě setkali s oba termíny. Ikdyž je občas někdo používá jako jeden termín, pravdou je, že jsou to dva rozdílné pojmy.

  • Autentizace je proces ověřování identity uživatele, systému nebo entity. Jejím hlavním cílem je odpovědět na otázku: „Kdo jste?“ Uživatel obvykle poskytuje přihlašovací údaje, jako je uživatelské jméno a heslo, bezpečnostní token nebo dokonce biometrická data, například otisk prstu.

  • Autorizace, na druhé straně, je proces určování, jaké akce, zdroje nebo služby může autentizovaný uživatel používat. Zaměřuje se na otázku: „Co máte povoleno dělat?“ Například uživatel může mít oprávnění zobrazit a upravit dokument, přistupovat ke specifickým API endpointům nebo pracovat s určitou databází.


Authentication types

V dnešním článku se zaměřímě na nejčastějí typy API autentizace, které, teoreticky, se dají implementovat v Power Query, specificky se dají napsat v jazyku M.

Poznámka; Power Query obsahuje spoustu nativně podporovaných konektorů, které disponují uživatelským oknem pro zvolení typu autentizace. Nicméně, v tomto článku se zaměříme na takové konektory, které toto okno implementované nemají a musíme je napsat pomocí jazyka M, konkrétně API zdroje.

Seznam základní typů autentizace, na které mrkneme:

Symbol kotvy vás pošle na část článku se zvoleným typem

Seznam ostatních typů, které zde probírat nebudeme:


Autentizace v Power Query

V Power Query se většinou spoléháme na okno, které nám dovoluje pro nativní konektory zvolit autentizační způsob pomocí "myši", případně ho jednoduše zadat do připravených polí.

Známé okno, které nám umožní zvolit autentizační metodu.



Pokud se chceme připojit ke zdroji, který není zahrnut mezi nativní možnosti, musíme si vytvořit toto „autentizační okno“ sami pomocí jazyka M. Bez ohledu na zdroj vás Power Query stále vyzve k výběru metody autentizace prostřednictvím grafického rozhraní. Abychom mohli metodu definovat ručně v jazyce M (zejména pomocí hlavičky Authorization), je nutné v grafickém autentizačním okně vybrat možnost „Anonymous“. Tato volba nám umožní specifikovat požadovanou metodu autentizace přímo v kódu M. Pokud nevyberete Anonymous a přesto definujete hlavičku Authorization, zobrazí se tato chybová zpráva:

Expression.Error: The 'Authorization' header is only supported when connecting anonymously. These headers can be used with all authentication types: Accept, Accept-Encoding, Accept-Charset, Accept-Language, Cache-Control, Content-Type, If-Modified-Since, Prefer, Range, Referer
Chcete-li tento problém vyřešit, přejděte do Nastavení zdroje dat, najděte svůj zdroj, klikněte na Upravit oprávnění, poté na Upravit a vyberte možnost Anonymous (jak je znázorněno na obrázku výše).

Implementace v Power Query


Anonymous


Autentizace typu Anonymous umožňuje uživatelům přistupovat ke zdroji dat bez zadání jakýkoliv přihlašovacích údajů. Tento typ autentizace se v business sféře používá jen zřídka. Naopak je běžně využíván u veřejně dostupných informací, jako jsou volně přístupné databáze nebo sbírky obsahu – například obrázky koťat 🐈. Můžeme mrknout na obě sbírky.

Pokud jste nikdy nepracovali s API v Power Query, mrkněte nejdřív na tento článek.

Příklad obecného zápisu:

let
    request = Json.Document(
        Web.Contents(
            "url",
            [
                RelativePath = "relativePath"
            ]
        )
    )
in
    request 

Příklad 1 (Veřejná databáze zranitelností):

let
    sourceVulnerabilities = Json.Document(
        Web.Contents(
            "https://services.nvd.nist.gov",
            [
                RelativePath = "rest/json/cvehistory/2.0"
            ]
        )
    )
in
    sourceVulnerabilities
Response
Response

Příklad 2 (Veřejná kolekce obrázků koček):

let
    sourceCat = Json.Document(
        Web.Contents(
            "https://api.thecatapi.com",
            [
                RelativePath = "v1/images/search?",
                Query = [limit = "1"]
            ]
        )
    ),
    firstRecord = sourceCat{0} // {0} vezme první záznam z dané kolekce
in
    firstRecord
Response
Odpověď

Jak vidíte, vytvořili jsme jednoduchý HTTP požadavek bez nutnosti Autorizační hlavičky.


API Key


Tato metoda zahrnuje použití statického klíče, obvykle bez data expirace, který je často generován prostřednictvím dokumentačního portálu nebo uživatelského rozhraní poskytovatele API. Pro vygenerování klíče budete pravděpodobně potřebovat uživatelský účet s konkrétními oprávněními, aby klíč zajistil přístup ke všem potřebným zdrojům. Tento přístup je jednoduchý a vhodný pro bezplatná nebo veřejná API. Jeho největší nevýhodou však je, že jelikož je klíč často bez data vypršení, jeho náhodný únik může znamenat nevyžádaný přístup k vašim datům z třetích stran.


V Power Query používáme dva způsoby, jak se ověřit pomocí API Key:

  • Hlavička požadavku: Můžete vepsat klíč do speciálního x-api-key headeru.

let
    request= Json.Document(
        Web.Contents(
            "url",
            [
                RelativePath = "relativePath",
                Headers = [
                    #"x-api-key" = "vygenerovaný API Key"
                ]
            ]
        )
    )
in
    request

Někdy můžete vidět i využití v rámci Autorizačního headeru: Authorization=ApiKey vášklíč

  • Query Parametr: Případně můžete vepsat klíč i jako jeden z parametrů "query stringu", tento parametr se nazývá: api_key.

Pozor; odesílání API klíče prostřednictvím dotazovacího řetězce (query string) je nebezpečné, protože může být zaznamenáno v URL adresách nebo serverových logech. Pokud je to možné, používejte místo toho autorizační hlavičku nebo jiné bezpečnější metody.
let
    request = Json.Document(
        Web.Contents(
            "url",
            [
                RelativePath = "relativePath",
                Query = [
                    api_key ="vygenerovaný API Key"
                ]
            ]
        )
    )
in
    request

Pro příklad, předchozí Cat API nám dovoluje využít i API Key jako způsob autentizace:

V obou případech se náš klíč schovává pod parametrem: "cat_api_key"

Příklad 1 (hlavička požadavku):

let
    sourceCat = Json.Document(
        Web.Contents(
            "https://api.thecatapi.com",
            [
                RelativePath = "v1/images/search?",
                Query = [
                    limit = "1"
                ],
                Headers = [
                    #"x-api-key" = cat_api_key
                ]
            ]
        )
    ),
    firstRecord = sourceCat{0} // {0} vezme první záznam z dané kolekce
in
    firstRecord

Příklad 2 (query parameter/string):

let
    sourceCat = Json.Document(
        Web.Contents(
            "https://api.thecatapi.com",
            [
                RelativePath = "v1/images/search?",
                Query = [
                    limit = "1",
                    api_key = cat_api_key
                ]
            ]
        )
    ),
    firstRecord = sourceCat{0} // {0} vezme první záznam z dané kolekce
in
    firstRecord

Bearer Token


Bearer tokeny jsou běžnou metodou pro efektivní přístup k API. Jedná se o generovaný token, který se používá v hlavičce Authorization s předponou "Bearer". I když se mohou zdát podobné API klíčům, největší rozdíly spočívají v jejich životnosti a metodách generování. Bearer tokeny lze regenerovat prostřednictvím uživatelského účtu na webu poskytovatele API (podobně jako API klíče), často s možností nastavit datum expirace. Bezpečnějším přístupem je přidat další vrstvu ochrany pomocí krátkodobých obnovovacích tokenů (refresh tokens), které obvykle expirují během několika minut.


Příklad obecného zápisu:

let
    request = Json.Document(
        Web.Contents(
            "url",
            [
                RelativePath = "relativePath",
                Headers = [
                    Authorization = "Bearer test_token"
                ]
            ]
        )
    )
in
    request

Pro reálný příklad, použijeme existující testovací API:

let
    request = Json.Document(
        Web.Contents(
            "https://httpbin.org",
            [
                RelativePath = "bearer",
                Headers = [
                    Authorization = "Bearer test_token"
                ]
            ]
        )
    )
in
    request

Basic


Tato metoda je velmi podobná běžnému zadávání uživatelského jména a hesla, jaké znáte z formulářů. Je zde však jeden další krok: musíte zformátovaný řetězec user:password zakódovat do formátu Base64. Podobně jako u Bearer tokenu se také používá hlavička Authorization s klíčovým slovem jako předponou – v tomto případě "Basic".


Pozor! Kódování není totéž co šifrování, takže pokud někdo získá váš zakódovaný řetězec, může jej snadno dekódovat. Zveřejnění takového řetězce mimo vaši organizaci představuje bezpečnostní riziko, podobně jako byste si metaforicky nechali na stole papírek s uživatelským jménem a heslem. Z tohoto důvodu některá API využívají generované časově omezené tokeny spárované s vaším uživatelským jménem, přičemž výsledný řetězec je zakódován ve formátu username:token.


Příklad obecného zápisu:

let
    user = "user", // příklad: user@org.com
    password = "password", // heslo nebo vygenerovaný token
    base64 = Binary.ToText(Text.ToBinary(user & ":" & password), BinaryEncoding.Base64), // zakóduj to do Base64
    request = Json.Document(
        Web.Contents(
            "url",
            [
                RelativePath = "relativePath",
                Headers = [
                    Authorization = "Basic " & base64
                ]
            ]
        )
    )
in
    request

Pro tento způsob autentizace nemám dobrý reálný veřejný příklad, nicméně pokud jste někdy pracovali s JIRA Cloud, mrkněte jak například získáte úkoly přiřazené na vámi použitý účet:

let
    user = "user@myorg.com", // vyměnit za za váš email
    password = "generated_token_through_your_profile", // vyměnit za váš API token
    base64 = Binary.ToText(Text.ToBinary(user & ":" & password), BinaryEncoding.Base64), // Encode user:password to Base64
    request = Json.Document(
        Web.Contents(
            "https://myorg.atlassian.net",
            [
                RelativePath = "rest/api/3/search?",
                Query = [
                    jql = "assignee=currentUser()",
				  fields = "created,summary"
                ],
                Headers = [
                    Authorization = "Basic " & base64
                ]
            ]
        )
    )
in
    request

OAuth 2.0


Tak, pojďme mrknout na současného krále autentizace. OAuth 2.0 je otevřený standard pro autorizaci, který umožňuje aplikacím přistupovat k uživatelským datům jménem uživatele, aniž by musely mít přístup k jeho přihlašovacím údajům. Funguje tak, že vydává přístupové tokeny třetím stranám poté, co uživatel udělí souhlas prostřednictvím autorizačního serveru. Tyto tokeny se pak používají v API požadavcích k bezpečnému přístupu k chráněným zdrojům.


Jednoduše řečeno. Místo toho, abyste třetí straně přímo poskytli své uživatelské jméno a heslo, projdete přes důvěryhodnou službu autentizace, kde udělíte aplikaci povolení přistupovat pouze k určitým částem vašich dat. Aplikace pak obdrží speciální klíč (přístupový token), který jí umožní provádět jen ty akce, které jste schválili. Vaše přihlašovací údaje tak zůstávají v bezpečí a máte kontrolu nad tím, k čemu má aplikace přístup.


Tato metoda je často používána při práci s Microsoft API, například s Power BI REST API. Proces začíná registrací vaší aplikace v Azure Portal, kde získáte potřebné klientské údaje, jako je client ID a client secret. Tyto údaje následně použijete k žádosti o přístupový token pro třetí stranu, v tomto případě Power BI REST API. Přístupový token se obvykle chová jako Bearer token, takže jej zahrnete do hlavičky Authorization API požadavků ve formátu: "Bearer generated_token". Tím aplikace bezpečně přistupuje k API jménem uživatele, aniž by potřebovala jeho přihlašovací údaje.


I když se počáteční požadavky na získání přístupového tokenu mohou lišit podle konkrétní služby, sdílí obvykle podobnou strukturu. Zde je obecný příklad:


let
    // Sestavte tělo požadavku jako záznam s potřebnými parametry pro získání tokenu
    requestBodyQuery = [
        grant_type = "<grant_type>", 
        // Typ požadovaného grantového procesu (např. client_credentials)

        client_id = "<client_id>",
        // Client ID vaší aplikace

        client_secret = "<client_secret>", 
        // Client Secret vaší aplikace

        scope = "<scope>"                   
        // Rozsah přístupu, který požadujete
    ],
    
    // Převést tělo požadavku na URL-kódovaný řetězec požadovaný pro POST požadavek
    requestBodyContent = Text.ToBinary(Uri.BuildQueryString(requestBodyQuery)),
    
    // Vytvořte HTTP POST požadavek na token endpoint
    request = Json.Document(
        Web.Contents(
            "url", // Nahraďte základní URL endpointu pro token
            [
                RelativePath = "relativePath", // Nahraďte specifickou cestu k token endpointu
                Headers = [
                    #"Content-Type" = "application/x-www-form-urlencoded" // Určete typ obsahu pro URL-kódovaná data
                ],
                Content = requestBodyContent // Zahrňte URL-kódované tělo do požadavku
            ]
        )
    ),
    
    accessToken = request[access_token] // Získá hodnotu "access_token" z JSON odpovědi
in
    accessToken

Nejdůležitější částí je tělo požadavku. Zde specifikujete informace o registrované aplikaci, například její client_secret a client_id. Poté použijeme obsah (Content) a hlavičku Content-Type, abychom funkci předali nově vytvořený dotaz. Použil jsem funkci Uri.BuildQueryString, která přijímá záznam a převádí jej na jednoduchý URI řetězec. Hlavním přínosem této funkce je pomoc s escapováním speciálních znaků a kombinací polí pomocí "&". Výsledný escapovaný a kombinovaný záznam vypadá takto:

grant_type=%3Cgran_type%3E&client_id=%3Cclient_id%3E&client_secret=%3Cclient_secret%3E&scope=%3Cscope%3E

Můžeme použít tento typ, protože jsme specifikovali Content-Type jako application/x-www-form-urlencoded (též známo jako typ MIME). Tento typ požaduje páry "jméno-hodnota", proto jsme vytvořili jednoduchý záznam s poli a jejich hodnotami.

Obecný zápis vypadá takto:

field1=value1&field2=value2&field3=value3

Tato část je potom přeložena do toku bytů (binary data), skrz definici těla požadavku. V Power Query používáme funkci Text.ToBinary() pro přeložení dat.


Pokud bychom použili reálný příklad, dostali bychom něco takového:


Jako odpověď dostaneme token_type jako Bearer (poukazuje na to, že později využijeme předponu "Bearer "), informaci o vypršení tokenu - expiration (platný na jednu hodinu), a pak vlastní access_token, který potom použijeme pro volání aplikace třetí strany.


Pro dokončení volání aplikace třetí strany, přepoužijeme to, co jsme se naučili v sekci o Bearer tokenu, kde token právě nahradíme naším nově vygenerovaným access_token(em).

let
    request = Json.Document(
        Web.Contents(
            "url",
            [
                RelativePath = "relativePath",
                Headers = [
                    Authorization = "Bearer acess_token"
                ]
            ]
        )
    )
in
    request

Abych vám poskytl malou ukázku, jak vytvořit OAuth 2.0 pro aplikaci specifickou pro Microsoft, v tomto případě Power BI REST API, můžete se inspirovat tímto příkladem:


let
    requestBodyQuery = [
        grant_type = "client_credentials",
        client_id = "<client_id>", // nahradit
        client_secret = "<client_secret>", // nahradit
        scope = "https://analysis.windows.net/powerbi/api/.default"
    ],
    
    requestBodyContent = Text.ToBinary(
        Uri.BuildQueryString(requestBodyQuery)
    ),
    
    request = Json.Document(
        Web.Contents(
            "https://login.microsoftonline.com",
            [
                RelativePath = "<yourorg>.onmicrosoft.com/oauth2/token", // napsat svoji organizaci
                Headers = [
                    #"Content-Type" = "application/x-www-form-urlencoded"
                ],
                Content = requestBodyContent
            ]
        )
    ),
    
    accessToken = request[access_token]
in
    accessToken

S výsledným accessToken(em), můžete vytvořit požadavek například pro Power BI REST API Get Activity Events, zde píšu, jak na to více do hloubky.


Shrnutí


Prozkoumali jsme pět autentizačních metod v Power Query. Typ autentizace Anonymous nevyžaduje přihlašovací údaje a je vhodná pro veřejná data. API Key využívá unikátní klíč poskytnutý API, který je nutné udržovat v bezpečí. Bearer Token zahrnuje tokeny s nastavitelnou životností, které se přidávají do hlavičky Authorization jako "Bearer <token>", což zvyšuje bezpečnost díky expiraci a obnovování tokenů. Basic authentication odesílá Base64-kódované uživatelské jméno a heslo v hlavičce Authorization a měla by být používána pouze přes zabezpečené připojení. Nakonec OAuth 2.0 poskytuje bezpečný přístup bez sdílení osobních přihlašovacích údajů pomocí přístupových tokenů získaných důvěryhodným autorizačním procesem. Každá metoda nabízí různé úrovně bezpečnosti a je vhodná pro různé scénáře při připojování ke zdrojům dat v Power Query.

Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page