19 Dec

Konstruáljunk web API-t - 2. felvonás


Amikor az ember webről beszél, a legtöbb esetben színes weboldalakat képzel el, ezerféle közösségi platform belépéssel, ahol az ember minden mozzanatát lépésen tudják követni különböző módszerekkel, hogy a leginkább testreszabott élményt kapja. Ha bejelentkezünk egy oldalra, akkor a következő oldalbetöltéskor már az üdvözlő képernyő fogad, azt a hamis érzést keltve, hogy a weboldal tudja, hogy pontosan kik is vagyunk. Ez persze közel sem igaz, csupán a böngészőnk által küldött sütiben szerepel egy session ID, amivel azonosítanak bennünket és ezáltal hozzánk igazíthatják az oldal tartalmát. Ehhez viszont az kell, hogy a böngésző süti ide-oda közlekedjen a kérésekben/válaszokban.

Azt már tudjuk régről, hogy a HTTP az egy ún. stateless protokoll, vagyis a két egymást követő lekérés közt nincs semmiféle kapcsolat, állapotváltozás. Ezt hivatott áthidalni az imént említett sütis megoldás. Azonban amikor REST webservicekről beszélünk, ott ez a sütis módszer nincs jelen. A korábbi példákban ez nem is okozott gondot, hiszen még nem volt szó arról, hogy ki mit is csinálhat az adott REST erőforrásokkal. Viszont mi a helyzet akkor, ha bizonyos műveleteket csak adott jogosultság mellett szeretnénk megengedni? Valamilyen formában tudtára kell adjuk a szervernek, hogy mégis kik vagyunk, ami alapján ő vagy végrehajtja az említett műveletet, vagy egy jól irányzott 401-es válasszal finoman elutasít bennünket. Ilyen műveletek lehetnek pl. azok, amikor törölni akarunk egy elemet, hozzá akarunk adni, módosítani, netán valakinek a privát dolgaiba akarunk kutakodni.

Cikkünkben belepillantást nyerünk abba, hogy mi is az OAuth2.0 protokoll és hogy segíthet nekünk a fentiekben, third party vagy épp a saját API-nk használatakor.

Először is jöjjön néhány példa, amivel letisztázzuk, hogy mi is a különbség az authorizáció és authentikáció között.

  • Authentikáció (ki vagyok Én?)

  • Authorizáció (bemehetek-e a páncélterembe?)

  • Terrence Hill (Te mondd, hogy rablótámadás, a Te hangod mélyebb!)


Az alapkoncepció a korábban említett webes esetben egy kéttényezős authentikáció, ami legtöbb esetben egy felhasználónév/jelszó párost jelent. Ezt elküldjük és a backend valami csodás sessionben eltárolja, amit rólunk tudni kell, pl azt hogy milyen role-t töltünk be a rendszerben, aztán ebből kiszüttyögi, hogy megváltoztathatjuk -e a /etc/passwd fájlt vagy sem. Ez utóbbi folyamat az authorizáció.

Na most ez szép és jó, ha a rendszer a sajátunk és közvetlen kapcsolatban állunk a szerverrel. Azonban akadnak esetek, mégpedig jó sok eset, mikor nem ez a helyzet.

Tegyük fel, hogy a felhasználónév/jelszó párosunk egy olyan kulcs, ami mindent nyit, ami a miénk, a házat, a kocsit, a bankszámlát, na meg képes felnyitni a barátnőnk/barátunk szemét is, hogy mennyi időt töltünk a gép előtt, tehát minden jogosultsággal rendelkezik.

Aztán tegyük fel, hogy van egy szolgáltatás, amivel a bankszámlánkat tudjuk menedzselni, de ennek a szolgáltatásnak szüksége lenne a hozzáférésre. A mi "mesterkulcsunkat" mégsem adhatjuk oda, hiszen azzal az adott szolgáltatás simán vissza is élhet a 30 éves Wartburgunkat is nyitó kulccsal, így kell valami alternatívát találni.

A megoldást úgy képzeljük el, hogy elmegyünk a kulcskészítőhöz a mátrixból és megmutatjuk neki a kulcsunkat, amiért ő ad egy másik kulcsot, ami csak a bankunkhoz ad hozzáférést, ott is csak limitált ideig. Aztán ezt a kulcsot odaadjuk a bankos hölgyikének és ő ezzel tud garázdálkodni a nevünkben. Na, ezt a folyamatot a szakma tolvajnyelvén 3-legged OAuth authentikációnak hívjuk.

Na de mi is az egész OAuth lényege? Mitől lenne ez nekünk jó?
Az OAuth segítségével úgy tudjuk megosztani a saját kis privát dolgainkat (képeket, videókat, stb.) egy másik oldallal, hogy annak az oldalnak nem adjuk ki jelszavunkat és felhasználónevünket.

Már az elején fontos leszögeznünk, hogy az OAuth nem segít biztonság szempontjából, tehát ha plaintext küldünk el valamit, az OAuth mellett is plaintext marad, ennélfogva nem mentesít az SSL és hasonlók alól.

Na de nézzük csak hogy is épül fel az egész!

Az OAuth standard három különböző szerepkört határoz meg:
  • client (Third-party application)

  • server (The API)

  • resource owner (User)


A hagyományos kliens-szerver modelben (amit ugye a RESTful API-knál is használunk) a kliens használja a saját hitelesítő adatait, hogy elérje az erőforrásokat egy szerveren. A hitelesítő adatok a klienshez tartoznak, a szervert nem érdekli, hogy az honnan is jött, vagy a hitelesítő adatok valóban a klienstől jöttek-e, amíg megegyeznek azzal, amit vár, a kérést teljesíti.


Akadnak esetek azonban, amikor a kliens másvalaki nevében akar tevékenykedni. Amikor ilyen helyzet áll fent, akkor egy felhasználó használja az adott klienst, és a kliens a felhasználó nevében akar cselekedni.

Ilyenkor a kliens nem a saját hitelesítő adatait fogja használni, hanem az adott felhasználójét, ez legtöbbször egy felhasználónév/jelszó páros lesz.

Akkor most menjünk kicsit gyakorlatiasabb irányba, mégpedig úgy, hogy képzeljük el, a klienst mint egy webes alkalmazás, aminek a frontendje a felhasználó gépén fut, a backendje pedig egy szerveren.

Na most a probléma ott kezdődik, hogy az imént mondtuk, hogy egy weboldal szeretné használni a mi felhasználónkat, ahhoz hogy egy másik weboldalon végezzen ezt-azt. Mi garantálja, hogy nem élnek vissza vele?

Először nézzük mi is a helyzet, ha már egy kész API-t akarunk használni (az API és az Oauth server lehet külön is, de most egyszerűsítünk). Tegyük fel, hogy van egy alkalmazásunk, amivel a felhasználóink le tudják kérdezni a bankszámlájukhoz tartozó számlatörténetet. Ez az alkalmazásunk használja majd a bank serverét, a felhasználó (resource owner) nevében. Ahhoz, hogy ezt meg tudja tenni, be kell regisztrálnunk a szervernél. Ehhez meg kell adnunk pár alap információt: app neve, weboldal, logó, stb. Ami nagyon fontos, hogy meg kell adni a redirect URI-t, amire visszaredirektálja a felhasználókat.

A redirect URI azért fontos, mert csak erre redirektálhat vissza a rendszer, ráadásul meg szokták követelni, hogy biztonságos protokollon történjen, https-el, de majd erre is visszatérünk.

Amikor az alkalmazásunkat regisztráljuk, kapunk egy clientID-t és egy client_secret-et. Az előbbi egy publikus információ, az utóbbi viszont titkos.

Az OAuth folyamat első lépése az ún. authorizáció. A böngészős alkalmazásoknál ez úgy történik, hogy a szerver biztosít egy UI-t a felhasználó számára, ahol engedélyezheti az elérést.

Amikor a felhasználó be akar lépni a weboldalunkra, akkor a Login gomb megnyomásával átirányítjuk a felhasználót egy ilyen URL-re:
https://bank-oauth2-server.com/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=reports

Az URL-ben átadtuk hogy egy ún authorization code-ot várunk vissza, a client_id-t hogy tudja kiről is van szó, valamint egy redirect_uri-t és megadtuk, hogy a riportokhoz szeretnénk hozzáférni.

A szerver erre a kérésre ellenőrzi, hogy létezik-e a megadott client_id és a hozzá tartozó redirect_uri is megfelelő-e, ha igen, akkor megjelenít a felhasználónak egy hasonló felületet:

Ha a felhasználó arra kattint, hogy elfogadja a kérést, akkor a szerver a kapott redirect_uri-ra redirektálja a felhasználót, de GET paraméterként megkapjuk az authorizációs kódot:
https://bank-oauth2-client.com/callback?code=AUTH_CODE

Erre a lépésre azért van szükség, mert a GET paraméterek között nem adhatjuk ki a client_secret-et. A szerveren egy authorization_codes táblába (vagy épp ami a datastore) letárolja ezt a kódot és a hozzá tartozó client_id/user_id párost.

Ez a felület már általunk íródott, úgyhogy itt megint átvesszük az irányítást és a kapott kóddal küldünk egy POST kérést a szerverünkről:
POST https://api.bank-oauth2-server.com/token
 grant_type=authorization_code&
 code=AUTH_CODE&
 redirect_uri=REDIRECT_URI&
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET

Ha minden rendben, akkor a szerver egy access_tokennel válaszol cserébe:
{
 "access_token":"RsT5OjbzRn430zqMLgV3Ia"
}

kivéve, ha valami hiba volt:
{
 "error":"invalid_request"
}

A fent kapott access_tokennel pedig az adott user nevében tudunk betyárkodni, DE csak a report scope alá eső műveleteket, na de mégis hogy?

A kéréseink Header mezői közé kell felvennünk azt:
GET https://api.bank-oauth2-server.com/reports/me

Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia

Ezzel a szerver megkapja a tokent, megnézi a saját adatbázisában, hogy milyen scope-okkal rendelkezik, mi is az adott kéréshez szükséges scope és annak függvényében válaszol vagy sem.

Bumm, ennyi volt az egész! Egyszerűnek tűnik, ugye?

Viszont maga az OAuth2 server már közel sem lesz ilyen egyszerű. A következő cikkben megnézzük milyen lehetőségeink vannak PHP-vel, mégpedig kipróbáljuk a Passport modulját a Laravel 5.3-nak és mélyebbre ásunk a rendszer működésébe, hogy mi miért is történik!

Hozzászólások betöltése
2014-2017 © Letscode.hu. Minden jog fenntartva. Build verzió: 1.2.37

Mik azok a sütik?


As is common practice with almost all professional websites this site uses cookies, which are tiny files that are downloaded to your computer, to improve your experience. This page describes what information they gather, how we use it and why we sometimes need to store these cookies. We will also share how you can prevent these cookies from being stored however this may downgrade or 'break' certain elements of the sites functionality.

Áltálnos információkat nyújthat ez a Wikipedia cikk a HTTP sütikről...

Hogy használjuk a sütiket?


We use cookies for a variety of reasons detailed below. Unfortunately is most cases there are no industry standard options for disabling cookies without completely disabling the functionality and features they add to this site. It is recommended that you leave on all cookies if you are not sure whether you need them or not in case they are used to provide a service that you use.

Sütik kikapcsolása


You can prevent the setting of cookies by adjusting the settings on your browser (see your browser Help for how to do this). Be aware that disabling cookies will affect the functionality of this and many other websites that you visit. Disabling cookies will usually result in also disabling certain functionality and features of the this site. Therefore it is recommended that you do not disable cookies.

A sütik amiket mi használunk


This site offers newsletter or email subscription services and cookies may be used to remember if you are already registered and whether to show certain notifications which might only be valid to subscribed/unsubscribed users.

In order to provide you with a great experience on this site we provide the functionality to set your preferences for how this site runs when you use it. In order to remember your preferences we need to set cookies so that this information can be called whenever you interact with a page is affected by your preferences.


Harmadik féltől származó sütik


In some special cases we also use cookies provided by trusted third parties. The following section details which third party cookies you might encounter through this site.

This site uses Google Analytics which is one of the most widespread and trusted analytics solution on the web for helping us to understand how you use the site and ways that we can improve your experience. These cookies may track things such as how long you spend on the site and the pages that you visit so we can continue to produce engaging content.

For more information on Google Analytics cookies, see the official Google Analytics page.

The Google AdSense service we use to serve advertising uses a DoubleClick cookie to serve more relevant ads across the web and limit the number of times that a given ad is shown to you.

For more information on Google AdSense see the official Google AdSense privacy FAQ.

We also use social media buttons and/or plugins on this site that allow you to connect with your social network in various ways. For these to work the following social media sites including; Facebook, will set cookies through our site which may be used to enhance your profile on their site or contribute to the data they hold for various purposes outlined in their respective privacy policies.


More Information


Hopefully that has clarified things for you and as was previously mentioned if there is something that you aren't sure whether you need or not it's usually safer to leave cookies enabled in case it does interact with one of the features you use on our site. However if you are still looking for more information then you can contact us through one of our preferred contact methods.

Email: fejlesztes@letscode.hu

Bezárás