Intranet alkalmazások architektúrája

Sok mindent lehet intranet alkalmazásnak tekinteni az SMTP levelezéstől kezdve, az Interneten keresztüli titkosított csatornákkal összekötött LAN-okon át, a hagyományos alkalmazásokig. Ez a fogalom leggyakrabban azonban olyan alkalmazást jelent, amelyet Web böngésző segítségével lehet használni. Ilyen alkalmazások ma már vannak, és egyre többen lesznek. A hagyományos alkalmazások egymás után kapnak Webes felületet, és olyan új alkalmazások is kialakulnak, amelyek eddig nem léteztek, és amelyek hatékony megvalósítását a Web technológia teszi lehetővé. Ugyanakkor a Webet elsősorban nem arra találták ki, hogy univerzális kliens felület legyen kliens-szerver alkalmazásokhoz annak ellenére, hogy úgy tűnik, ez válik az elsődleges felhasználási móddá. A Web eredeti felhasználása információpublikálás, amely csak később lett kiegészítve olyan elemekkel, amelyek lehetővé teszik az eredetihez képest fordított, a kliens felől a szerver felé haladó információk továbbítását. Ezekkel az elemekkel már lehetővé válik Web alapú alkalmazások megírása, de sok olyan kérdés nyitva marad, amelyre nem ad a Web technológia egyértelmű választ.

CGI, ISAPI, NSAPI, FastCGI

A Web technológia a HTTP protokollon alapul. Ez a protokoll pedig nagyon egyszerű. Nem biztosít a mai követelményeknek megfelelő felhasználói azonosítást. Alapvetően kapcsolat nélküli információ cserét biztosít, ezért a http protokollnál nincs olyan fogalom, mint bejelentkezett felhasználó, vagy kilépés a rendszerből. Pedig ahhoz, hogy alkalmazásokat készítsenek a programozók, ezekre feltétlenül szükség van.

A Webes alkalmazások megismeréséhez még egy szabványt, vagy szabvány csoportot ismerni kell. Ezek azok a szabályok, amelyek azt határozzák meg, hogy a Web szerver program, amely a hálózaton keresztül HTTP protokollal kommunikál a böngészővel, hogyan és mikor indítja el a szerver oldali alkalmazást, hogyan adja át neki a HTTP kérésben szereplő adatokat, amelyek alapján a program el tudja látni feladatát, és hogyan veszi át a program futási eredményeképpen születő, a HTTP válaszhoz szükséges információkat. A szabvány a Common Gateway Interface (CGI), amely a UNIX világ hagyományaihoz illeszkedve azt mondja, hogy a Web szerver a programot minden egyes HTTP kéréshez külön processzként indítja el, a kérésben szereplő paramétereket a parancssorban, a szabványos bemeneten és környezeti változókban adja át, a választ pedig a program szabványos kimenetéről veszi. Ez a szabvány elterjedt, és gyakorlatilag minden Web szerver támogatja. A gond vele az, hogy minden egyes kéréshez egy új processzt elindítani külön védett címtartománnyal egy kicsit túlzás, feleslegesen leterheli az operációs rendszert. Az olyan operációs rendszereknél ahol egy processz aránylag primitív, mint a UNIX-nál, ez nem okoz komoly lassulást, de a Windows NT vagy például az OpenVMS operációs rendszer alatt egy processz elindítása már komolyabb erőforrást igényel. Emiatt alakult ki két másik ajánlás is, az egyik a Microsoft ISAPI, a másik a Netscape NSAPI ajánlása. Ezek szerint az ajánlások szerint a Web szerver nem indít el egy külön processzt, hanem csak a Web szerver processzen belül egy külön szálat. Ez sokkal gyorsabb, kevésbé terheli le a rendszert. A hátránya a CGI-vel szemben az, hogy ezek nem széleskörűen támogatott eljárások, és mivel nincsenek külön memória területe lefoglalva, ezért a Web szerver és az egyes szálak nincsenek egymástól védve. Emiatt az ilyen módon indított alkalmazások kevésbé robusztusak, ha valamelyik szálban hiba történik az egész Web szervert, vagy UNIX-os terminológiával http démont kell újraindítani.

Végül, de egyáltalán nem utolsósorban mind a CGI, mind pedig az ISAPI és NSAPI megoldás hátránya, hogy egyáltalán nem biztosítanak folyamatos környezetet egy kliens szerver kapcsolathoz. Ha valaki "bejelentkezik" egy Web alkalmazásba, akkor a szerver oldalon futó alkalmazásnak kell gondoskodnia arról, hogy a felhasználót bejelentkezettként tartsa nyilván, figyeljen arra, hogy ha a felhasználó kimondottan nem jelentkezik ki, akkor is törölje a bejelentkezett felhasználók közül bizonyos idő elteltével, és minden ezzel járó feladatot elvégezzen. Azonban még ennél is komolyabb feladat az, hogy olyan alsóbb szintű szolgáltatások, mint adatbázis kapcsolat hatékony felhasználása nehézkes. Egy CGI alkalmazás, ha megnyit egy adatbázis kapcsolatot, például ODBC felületen keresztül, azt nem tudja nyitva tartani, mert maga a processz, amely megnyitja, véget ér, és a felhasználó újabb rendszerhez fordulásakor újra, és újra meg kell nyitni, és le kell zárni a kapcsolatot. A megoldás az lehet, ha a szerver oldali alkalmazás egy külön processzt indít el minden egyes felhasználó számára, amely azután nem ér véget, hanem mindaddig fut, amíg a felhasználó "be van jelentkezve", és amely megtartja a többi alkalmazással, például adatbázissal a kapcsolatot, és csak a felhasználó által kezdeményezett, vagy kidobási idő lejártával automatikusan végrehajtott kijelentkezéskor fejezi be működését. A közbenső események, és felhasználói kommunikáció során a Web szerver RPC-vel, socket felületen, vagy neves csatornán (named pipe) keresztül kommunikál a futó processzel.

Az is megoldás lehet, ha a CGI, ISAPI, NSAPI alkalmazás csak a legalapvetőbb feladatokat végzi el és az igazi funkcionalitást egy Windows NT szerviz vagy UNIX démon végzi el. Ez a megoldás lehetőséget ad arra, hogy a felhasználó bejelentkezésekor felépülő adatbázis kapcsolat csak a felhasználó kijelentkezésekor szakadjon meg, és ne kelljen minden egyes érintésnél újra felépíteni ezt a kapcsolatot. Ez a megoldás sokkal kevésbé terheli a gépet, és ennek megfelelően sokkal jobb teljesítményt nyújt, mint a teljesen a CGI, ISAPI, NSAPI programban megvalósított funkcionalitás, de még mindig nem választja szét operációs rendszer szinten az egyes felhasználói memória területeket, adatterületeket, és processzor időt. Ha a funkcionalitást nem egy démon, vagy szerviz valósítja meg, hanem minden egyes felhasználó számára a saját neve alatt futó processzt indít el a rendszer, akkor több más dolog mellett az operációs rendszer gondoskodhat az egyes felhasználói memória területek védelméről, vagy arról, hogy az egyes felhasználók ne használjanak fel túl sok számítási erőforrást. Azaz ne lépjék túl processzor kvótájukat, és ezzel ne terheljék le a többi felhasználó számára használhatatlanul lassúra a gépet. Persze ez csak olyan rendszerben képzelhető el, amelyik ismeri a processzor kvóta fogalmát.

A külön processzeknek gyakorlati jelentőségük is van. Valaki azt mondhatja, hogy ő nem fog olyan programot írni, amelyik túl sok erőforrást eszik, elveszti a lefoglalt memóriát stb. Vannak azonban olyan UNIX változatok ahol maguk a rendszerfüggvények teszik meg ezt. (Az Apache Web szerver dokumentációja szerint a Solaris néhány könyvtári rutinja ilyen, és ezért konfigurálhatók az Apache processzek olyan módon, hogy bizonyos számú http kérés kiszolgálása után leállnak, és a rendszer új processzt indít helyettük.)

A megoldás talán a legújabb, és még formálódó szabvány lehet, a FastCGI, amelyet az OpenMarket támogat. Jelenleg az OpenMarket Web szervere az egyetlen üzleti Web szerver, amelyik ezt a szabványt támogatja, valamint olyan ingyenes szerverek, mint az Apache, NCSA httpd. Sem a Microsoft, sem pedig a Netscape nem tették még le a voksukat e mellet a szabvány mellett. Várható azonban, hogy ingyenes programként meg fognak jelenni teljes értékű ISAPI és NSAPI felületű FastCGI megvalósítások, mint ahogy elkészítették a CGI FastCGI átjárót is (bár ez utóbbi csak fejlesztési célokra jó, elveszti azokat a tulajdonságokat, amitől a FastCGI fast, azaz gyors).

A FastCGI szabvány a CGI két feladatát szétválasztja. A CGI szabvány előírja azt, hogy a Web szerver hogyan indítja el az alkalmazási programot, vagy script-et, mint külön processzt, és azt, hogy hogyan kommunikál vele. A FastCGI szabvány nem törődik azzal, hogy egy processz hogyan indul el, ezt a Web szerverre, vagy valamilyen más szerverre bízza, csak azt írja le, hogy a Web szerver és a futó processz hogyan kommunikál.

A FastCGI szabvány a HTTP kérés tartalmát illetve a választ socket felületen keresztül küldi el az alkalmazásnak, és azon keresztül is fogadja a választ. Ez lehetővé teszi, hogy az alkalmazás ne ugyanazon a gépen fusson, mint a Web szerver, és talán ezt az előnyt nem akarták a szabvány fejlesztői azzal, hogy előírják a processzek kezelésének módját. A Web szerver a socket-en keresztül csomagokat küld az alkalmazásnak és a választ is így fogadja. Mivel az egyes http kérésekhez nem indul el új processz, mint a CGI esetében, ezért minden az adott FastCGI programra hivatkozó http kérés ugyanahhoz a processzhez fog elérkezni. Ezeket a kéréseket a Web szerver és FastCGI processz közötti kommunikációban a Web szerver által generált egyedi azonosítók hordozzák, amelyek megjelennek a processz és a Web szerver közötti minden egyes csomagban.

A FastCGI egyik előnye, hogy gyorsabb, hiszen nem kell minden egyes http kéréshez egy új processzt létrehozni. A másik nagy előnye, hogy nem feltétlenül kell a Web szerver gépen futnia az alkalmazásnak. A harmadik, és talán legnagyobb előnye, hogy a FastCGI processz az egyes http kérések között megtarthatja az állapotát memóriában, nem kell elvesztenie az adatbázis kapcsolatokat.

A hátránya, hogy ezzel több feladat hárul a fejlesztőkre. Fel kell készülniük arra, hogy amíg az egyik kérést kiszolgálják, újabb kéréseket kap ugyan a processz. Ezt pedig csak többszálú programozással lehet megoldani, amelyre például a Perl nyelv jelenlegi verziója 5, amely a Web programozás legkedveltebb nyelve, nem alkalmas. És más nyelveken sem túl egyszerű ilyen alkalmazások fejlesztése, főleg nem a hibakeresés.

Egy félmegoldás ennek feloldására az, hogy egy FastCGI alkalmazás több példányban is fut akár különböző gépeken, és a Web szerver mindig kiválaszt egyet az adott URL-hez rendelt processzek közül. Ezzel el lehet kerülni a többszálú programozást, és egyszerre több kérést is ki lehet szolgálni, egyszerre annyit, ahány processz elindult az alkalmazást futtatva. Viszont ez esetleg kevesebb, mint amennyit maga a rendszer elbír. Ezért ez csak félmegoldás, és ezzel elvész annak a lehetősége, hogy a processz a memóriában őrizze meg az állapotát és az adatbázis kapcsolatokat, hiszen hol az egyik, hol a másik processz indul el.

Emiatt egyes megvalósítások, de nem maga a FastCGI szabvány kitalálták a session affinity fogalmat. Ez azt jelenti, hogy egy session-höz tartozó http kérések mindig ugyan ahhoz a FastCGI processzhez kerülnek. Ha valaki valahogyan bejelentkezett, akkor ezentúl mindig ugyanaz a processz fogja a kéréseit kiszolgálni, amíg a session tart. A session fogalma azonban nem túl jól definiált. Eloszthatja a szerver a http kéréseket a processzek között a kérést feladó kliens oldal IP címe szerint. Ez gondot okoz az IP címet váltogató proxy szerverek mögött ülő felhasználóknak, pl. AOL. De eloszthatja kéréseket az URL bizonyos darabjai szerint. Ennek kezelése megjelenik a FastCGI programban, és ebben a pillanatban - mivel ez már nem a FastCGI specifikáció része - a program már egy adott Web szerverhez fog kötődni.

Kapcsolat tartás

A felhasználó azonosítására három megoldás lehetséges. Az első, használni a HTTP protokoll által támogatott "basic authentication", azaz alapszintű felhasználó azonosítást, amely azonban a nevének megfelelően nagyon alapszintű. A másik lehetőség a Microsoft Internet Explorer-be épített kérdezz-felelek azonosítás, amely viszont nem szabványos és minden más böngésző használót kizár a rendszerből. A harmadik lehetőség saját azonosító rendszert írni, amely annyira lehet biztonságos, amennyire a programozó paranoiás (azaz nagyon), viszont sok programozást igényel.

A http protokoll rendkívül egyszerű. A kliens és a szerver között a kapcsolat mindig a kliens kezdeményezésére jön létre. A kliens az IP protokoll felhasználásával megszólítja a szervert, és amikor az válaszol, létrejön egy csatorna. Ezen a csatornán keresztül a kliens elküldi az úgynevezett http kérést, amelyre a szerver a http választ adja, és ezek után lebomlik a kapcsolat. A szabvány újabb, 1.1 változata szerint lehetőség van a kapcsolat megtartására, és újabb http kérés elküldésére, ez azonban csak a több darabból álló dokumentumok letöltését gyorsítja, és ettől még a protokoll továbbra is kapcsolat nélküli. Ez azt jelenti, hogy nincs olyasmi, mint a telnet, vagy ftp kapcsolatnál a felhasználói bejelentkezés, és élő kapcsolat akkor is, amikor a kliens éppen nem cserél adatot a szerverrel.

Mint általában a többi TCP protokollnál, a http kérés és válasz is sor orientált szöveges protokoll, két részből áll: egy fejlécből, és egy testből, amelyeket egy üres sor választ el. A fejléc első sora jelzi, hogy a tartalom a http protokollnak megfelelő formátumú, és hogy milyen verziót használ a kliens vagy a szerver. A fejléc minden további sora tartalmazza a fejléc mező megnevezését, amely után egy kettőspont és szóköz áll, majd a mező értéke következik. Példaképpen egy nagyon egyszerű http válasz, amelyet egy Web szerver küldhet a böngészőnek:

HTTP/1.0 200 OK 
Content-type: text/html 


<html><head><title>Hello</title></head><body>Hello!</body></html>

Ezt a választ kapva a Web böngésző a "Hello" üzenetet jeleníti meg a felhasználó képernyőjén.

A http üzenetek fejlécében rengeteg járulékos információ foglalhat helyet. A kérésben a böngésző általában elküldi a saját típusát, verzióját, és hogy milyen operációs rendszeren fut, így a szerverek pontosan láthatják, hogy ki használ Netscape, ki Internet Explorer vagy éppen valamilyen más böngészőt, és ezt felhasználva például különböző módon küldhetik el ugyan azt az információt a különböző böngészőknek kihasználva azok speciális tulajdonságait. A kliens olyan információt is küldhet a szervernek, amely meghatározza, hogy egy információt milyen körülmények között kér. Előfordulhat, hogy már korábban letöltött valaki egy információt, és csak azt szeretné megtudni, hogy változott-e az adott oldal. Ilyenkor a fejlécmezők segítségével a böngésző mondhatja azt a szervernek, hogy csak akkor küldje át a hálózaton a dokumentumot, ha az újabb, mint egy bizonyos időpont. Megteheti a böngésző azt is, hogy egy félig letöltött kép folytatását kéri, amennyiben az nem változott azóta, hogy az első felét letöltötte.

A http válasz fejlécében a szerver olyan információkat küldhet, amelyek az oldal megjelenítését, tárolását, illetve a proxy szervereken keresztüli továbbítását vezérlik. Meghatározhatja a szerver, hogy egyes oldalakat ne tároljon a cache memóriájában egyetlen proxy vagy a böngésző sem. Ennek lehetnek biztonsági okai. Küldhet a fejlécben olyan állapot azonosító információkat, amelyeket a böngésző a legközelebbi http kérés fejlécében visszaküldhet. Ezeket hívják cookie-nak. Vagy küldhet a fejlécben olyan hibajelzést, amely hatására a böngésző felhasználói nevet és kulcsszót kérő ablakot jelenít meg a felhasználó előtt, és amely segítségével valamilyen "bejelentkezés" megvalósulhat.

A HTTP alapszintű azonosítás első lépése, hogy a szerver egy oldal lekérésekor hibaüzenetet küld a kliensnek, egy olyan hibakóddal, amely jelentése: Azonosítás nem megfelelő! Ekkor a böngésző egy kis ablakot nyit a képernyőn, és megkérdezi a felhasználótól a bejelentkezési nevét és jelszavát, majd pedig az előző HTTP kérést újra elküldi egy olyan fejlécmezővel kiegészítve, amely tartalmazza a felhasználói azonosítást. Ezt a mezőt minden további kéréssel is elküldi a böngésző. Ez olyan, mintha valakivel beszélgetve minden egyes mondat előtt újra be kellene mutatkozni.

A megoldás előnye, hogy a böngészők és a szerverek is támogatják ezt a megoldást, szabványos, és megfelelő biztonságot adhat például egy helyi hálózaton, amely fizikailag védett a lehallgatás ellen. Ugyanakkor ez a megoldás nem programozható szabványosan! Amíg a szabvány rögzíti, hogy hogyan kell elküldeni az azonosítási információkat, nem rögzíti azt, hogy a Web szerver program, és az ezt használó alkalmazás közötti kommunikációban ez az információ hogyan cserélődik. Ennek oka az, hogy a szabvány tervezői nem akarták a Web oldali alkalmazásokat üzemeltetők kezébe adni a jelszavakat, nem akarták, hogy egy egyszerű ki script hozzáférhessen a felhasználók jelszavához. Úgy gondolták, hogy ezt a fajta azonosítást támogatják majd maguk a Web kiszolgáló programok, például a Microsoft IIS, Netscape Web szerver vagy a szabadon terjeszthető, ingyenes Apache. Ez így is van, csak nem mindig elegendő. Ha egy olyan Web oldalt akar valaki elérni, amelyiknek a fájlrendszerben megadott védelme nem engedi a Web szerver processz számára, hogy olvassa, akkor a Web szerver az alapszintű azonosítást használva a felhasználó nevében próbál hozzáférni a fájlhoz, legyen az futtatható, vagy statikus HTML lap. Ezzel tehát megoldható, hogy az egyes oldalak, Web szerver oldali programok védettek legyenek, de a megoldás mégsem az igazi.

Gondoljunk a Web áruházra, mint nagyon egyszerű alkalmazásra. A Web áruházba "bemennek" a vásárlók, azonosítva vannak, hiszen valahol nyilván van tartva, hogy ki mit vásárol, mi van a kosarában, mi a hitelkártya száma stb. Tehát valahogy minden egyes http kérésnek hihetően, biztonságosan tartalmaznia kell a felhasználó azonosítását. Erre elvileg, de csak elvileg lehetne használni a szabványos alapszintű azonosítást, feltéve, hogy nem bánjuk, hogy a felhasználó kulcsszava minden egyes HTTP kérés során keresztül megy a hálózaton. Ebben az esetben minden egyes felhasználót fel kell venni az operációs rendszerbe, mint felhasználót például a Microsoft IIS esetében és ez nem feltétlenül biztonságos, és nem is biztos, hogy kivitelezhető.

Ha saját azonosítási és bejelentkezés nyilvántartási rendszer írására adja valaki a fejét, mint e cikk szerzője tette, akkor nyilván kell tartania a felhasználókat minden szükséges rendszer adattal együtt, és gondoskodni kell arról, hogy a felhasználók bejelentkezhessenek, és a bejelentkezés után a bejelentkezés nyilván legyen tartva, azaz ne kelljen minden egyes bejelentkezés után újra és újra bejelentkezni. Valahogyan gondoskodni kell arról, hogy a kliens minden egyes újabb kérésében legyen olyan információ, amely alapján biztonsággal azonosítani lehet a felhasználót. A biztonságos azonosítás olyan módon történhet, hogy a szerver a bejelentkezés után létrehoz egy véletlenszerű kulcsot, amelyet a HTTP válaszban elküld a kliensnek, és amelyet a kliens a következő HTTP kérésben visszaküld a szervernek. A szerver ellenőrzi, hogy ez a kulcs valóban ki lett-e adva azonosításra az adott felhasználónak, és ha igen, akkor egyéb paraméterek megvizsgálása után engedélyezi, vagy nem engedélyezi a HTTP kérés kiszolgálását. A kulcsot a biztonsági kívánalmaknak, és a paranoia fokának megfelelően lehet gyakrabban, vagy ritkábban változtatni. Ezen kívül lehetőség van olyan feltételek ellenőrzésére, mint, hogy a HTTP kérés ugyan arról az IP címről érkezett-e, mint ahonnan a felhasználó bejelentkezett, vagy ugyan azt a böngészőt használja-e, mint korábban, stb.

A kulcsinformáció elküldése a HTTP válaszban több lehetőség is van. Ha az alkalmazás úgy van megírva, hogy miden egyes HTML oldalt a szerver oldali alkalmazás generál, akkor a szerveralkalmazásnak olyan HTML fájlt generálhat, ahol minden egyes HTML referenciában az URL-ben a script neve után a paraméterek között szerepel az aktuális kulcs, illetve a formákban rejtett változókban van megadva. Ekkor a referenciát követve, vagy egy formát elküldve a böngészőből a felhasználó automatikusan elküldi a szerver által a HTML kódban elhelyezett kulcsot. Az előbbi esetben a CGI alkalmazás a parancssor paraméterek között, míg a második esetben a szabványos bemenetén kapott paraméterek között kapja meg a kulcsinformációt.

Egy másik lehetőség a kulcsinformáció süteményben való elhelyezése.

A süti - angolul cookie - egy olyan információ, amelyet a szerver a HTTP válasz fejlécében helyez el, és amelyet a kliens ettől kezdve egy ideig minden egyes HTTP kérés fejlécében elküld a szervernek. A szerver megadhatja azt az URL tartományt, amelynek a sütit el kell küldeni, illetve megadhat egy időtartamot, ameddig a süti érvényes. Ennek lejártakor a kliens elfelejti a sütit, és nem küldi többet a szervernek. Egy szerver megadhat több sütit egyszerre, vagy egymás utáni HTTP válaszokban. A kliens oldalon pedig lehetnek több szerverről kapott sütik is. A szerver által megadott tartomány vonatkozhat például csak a szerverre. Ebben az esetben a kliens a sütit csak az adott szervernek küldi el a további HTTP kérésekkel, de ha egy másik szerverről kér le a böngésző információt, akkor annak nem küldi el a sütit. De küldhet a szerver olyan sütit is, amely a szerver csak bizonyos részeire vonatkozik, például a /scripts alkönyvtárra, ebben az esetben a kliens csak a CGI scripteknek fogja elküldeni a sütit, ugyanezen szerveren a statikus Web oldalak lekéréséhez nem. Viszont lehetőség van arra is sajnos, hogy olyan tartományt adjon meg a szerver, amely alapján a kliens az egyik szervertől kapott sütit egy másik gépnek is elküldi. Ad abszurdum, az is elképzelhető, hogy a programozó lustasága miatt olyan tartományt ad meg a szerver, hogy azután a kliens a sütit annak lejáratáig minden gépnek elküldi.

A kliens minden olyan sütit elküld egy HTTP kéréssel, amely még nem járt le, és a kérésben szereplő URL benne van a süti érvényességi tartományában. Ez azt jelenti, hogy egy HTTP kéréssel a kliens akár nagyon sok sütit is elküldhet, jelentősen növelve a HTTP forgalmat, esetenként feleslegesen.

A sütik kezelése a felhasználó számára láthatatlan. Ha csak nem veszi valaki magának a fáradtságot, hogy szövegszerkesztővel beleeditáljon a megfelelő böngésző fájlokba, akkor a böngésző nem mutatja meg, hogy milyen tartalmú, lejáratú és tartományú sütit küld a HTTP kéréssel a szervernek, illetve, hogy az egyes szerverektől milyent kap. Emiatt és azért, mert a szerver által meghatározott tartományra nincsen megkötés a Netscape ajánlásában, a sütik komoly biztonsági rést jelenthetnek. Persze csak akkor, ha valamilyen szerveralkalmazást igénytelenül írnak meg, és nem figyelnek a felhasználó biztonságára.

Példaképpen tekinthetjük az Internetes áruházakat, mert éppen ezek között volt, vagy talán van is néhány olyan, amelyet hanyagul készítettek el, és emiatt a vevőik kerültek veszélybe.

Egy Internetes áruház használata során a felhasználó több lapon halad keresztül, miközben a virtuális kosarába rak megveendő árukat. Annak a nyilvántartása, hogy egy vevő kosarában milyen áru van és a vevő azonosítása általában sütikkel történik. A megoldás az lehet, hogy a vevő kap egy azonosítót, amelyet automatikusan a szerver generál vigyázva arra, hogy egy azonosítót ne adjon ki kétszer, és ezt elküldi a kliensböngészőnek. A vevő kosarában levő árukat egy adatbázis tarthatja nyilván, amelyben minden vevőhöz tartozik egy vagy több rekord tárolva az eddigi vásárlásait, a hitelkártyaszámát, nevét, szállítási címet stb.

Persze ez a szerver oldalon komoly erőforrást igényel. Az áruház üzemeltetője számára olcsóbb, és a programozók számára kényelmesebb, ha ezeket az információkat mind belepakolják a sütikbe, és keresztül küldik a hálózaton. Ekkor nem kell adatbázisban keresni a felhasználói azonosító alapján, hanem minden rendelkezésre áll a sütiből. És a hitelkártyaszámot lehet használni vevői azonosításra, hiszen az biztosan egyedi. A vevő pedig mit sem vesz észre a dologból, legfeljebb egy kicsit lassabb lesz a kommunikáció. Ezért ez a megoldás nem igazán elegáns. És esetleg minden egyes alkalommal a hitelkártya száma is átmegy a hálózaton. Ezért ez a megoldás nem igazán biztonságos. És ez még nem minden. Volt a hálózaton olyan bolt, amelynek programozói mindezen merényletek mellett még arra is lusták voltak, hogy rendesen beállítsák a sütik érvényességi tartományát, így a vevők a bolt meglátogatása, és egy esetleges vásárlást követően - amikor is megadták a hitelkártya számukat - minden meglátogatott Web szervernek elküldték ezeket az információkat. Ezért ez a megoldás egyáltalán nem biztonságos :-)

Ennek az az előnye, hogy nem kell minden egyes generált HTML oldalon gondoskodni arról, hogy a megfelelő kulcs információt felküldje a kliens. A hátránya viszont az, hogy nem minden böngésző képes kezelni a sütiket, és a szerver által egyszer már a kliensnek leküldött sütit nem lehet törölni, csak megvárni, amíg az lejár. Ha pedig egy kulcs még nem járt le, de az érvényessége már a vége felé jár, akkor újat kell a kliensnek adni. A rejtett változókban elküldött kulcs esetén ezt az új kulcsot fogja a következő alkalommal a kliens a szervernek visszaküldeni. Ha azonban a kulcsot a szerver és a kliens között süti hordozza, akkor az új kulcs kiadása után a szerver a régi kulcs lejáratáig azt is megkapja. Erre a szervernek külön figyelnie kell.

A sütinek még egy előnye van a rejtett változókkal szemben. A rejtett változók az oldalakhoz kötődnek, így ha a kliens oldalon a felhasználó a böngésző vissza gombját használva visszalép egy korábbi oldalra, akkor a rejtett változóban adott kulcsok közül azt fogja legközelebb a szervernek elküldeni, amit a szerver azzal az oldallal küldött le a kliensnek. Ha ez az oldal nagyon régen került a szerverről a böngészőhöz, akkor ez a kulcs esetleg már nem érvényes. Ha viszont a kulcsot egy süti hordozza, akkor nincsen ilyen gátja a böngésző navigációs eszközeinek használatában, mindig azokat a sütiket küldi el a böngésző, amelyeket legutoljára kapott meg, és amelyek még érvényesek.

A FastCGI szabvány is támogatja a saját azonosítási és engedélyezési rendszert, és segít az azonosítási programrészeket és a "valódi" funkcionalitást elválasztani. Ezt olyan módon teszi, hogy definiál ún. authorizer alkalmazásokat, amelyeket a http kérés kezdetekor lefuttat, még esetleg a http kérés törzsének megkapása előtt. Ezek az alkalmazások nem is kapják meg az egész http kérést, csak a fejlécben szereplő információkat. Ha a processz által visszaadott http válasz, amely a Web szerverhez és nem feltétlenül a klienshez megy tovább a 200 OK státusz kódot tartalmazza, akkor a Web szerver engedélyezettnek veszi a kérést, és továbbítja a megfelelő FastCGI alkalmazásnak, amelynek most már nem kell azzal törődnie, hogy kiszolgálhatja-e a kérést. Ha az authorizer alkalmazás egyéb kódot ad vissza, akkor a Web szerver elutasítottnak tekinti a http kérést, és az authorizer válaszát küldi vissza a kliensnek, mint http választ. Ilyenkor nem indul el az igazi FastCGI processz.

Összefoglalás

Mi lehet mindezeknek a végső konklúziója? Melyik felülete használjuk Web alkalmazások fejlesztéséhez? Természetesen nem lehet egyértelmű választ adni. Ha valaki olyan alkalmazást fejleszt, amely egyébként is nagyon kötődik a Windows NT szerver platformhoz, például használ OLE-n keresztül egyéb alkalmazásokat, akkor nyugodtan választhatja az ISAPI felületet. Ha nem fontos a Web szerver program cserélhetősége, és Netscape szervert használ, akkor használható az NSAPI. A CGI minden esetben használható, jól megvalósított, minimális a különbség az egyes változatok között. Nagyon jól használható azokban az esetekben, amikor az operációs rendszerek és a Web szerverek közötti hordozhatóságot kívánja valaki használni. A FastCGI egyenlőre inkább kísérletezésre való, még nem egészen kiforrott, de mindenképpen figyelembe kell venni, amikor valaki CGI alkalmazást fejleszt, hogy könnyen átvihető legyen majd FastCGI alá.

Referenciák

NSAPI http://www.netscape.com
ISAPI http://www.microsoft.com
FastCGI http://www.fastcgi.com
Perl http://www.perl.org
http://www.perl.com
CGI FAQ


Verhás Péter Home Page . . . . . . CGI röviden, tartalomjegyzék