Ez az előző cikk folytatása konkrét példakódokkal.

Adatbázis

Tegyük fel, hogy az adatbázisban fogjuk tárolni a felhasználókat.


CREATE TABLE WsApiUsers (
   ApiKey      Char(32) NOT NULL UNIQUE,
   SecretKey   VARCHAR(40) NOT NULL UNIQUE,
 PRIMARY KEY (ApiKey)
);

Az ApiKey egyedi azonosító a felhasználók azonosítására szolgál.
A SecretKey egy titkosító kulcs, ami nem összetévesztendő
a jelszóval. Ezzel a titkos kulccsal kell a felhasználónak titkosítania egy
sztringet (a sessionId-t), amit majd a kiszolgálótól kap.

Szükségünk van még egy adatbázis táblára, amelyben az
éppen aktív munkamenetek listáját fogjuk tárolni.
Minden munkamenetet az egyedi SessionID azonosít, és ehhez még különböző információk társulnak.

WsActiveSessions tábla oszlopai
SessionID A munkamenet egyedi azonosítója.
IP A kliens IP cime. Jól jöhet ez az információ, ha a későbbiekben úgy
döntünk, hogy feljavitjuk az autentikációt.
Például az autentikáció a jelszó és a felhasználói néven kívül ellenőrizné még a kliens IP címét is.
Csak egy bizonyos IP címről, vagy IP cím subnetről érkező SOAP üzeneteket engedne tovább. Így valamelyest
erősítenénk a webszolgáltatás biztonságát.
UserID Ez egy idegen kulcs, és a WsApiUsers adatbázis táblára mutat. Ha értéke NULL,
a kliens még nem jelentkezett be (nincsen autentikálva), kiléte ismeretlen.


CREATE TABLE WsActiveSessions (
	SessionID  Char(40) NOT NULL UNIQUE,
	IP         Char(32) NOT NULL,
 	UserID     SMALLINT UNSIGNED NULL,
 Primary Key (SessionID),
 FOREIGN KEY (UserID) REFERENCES WsApiUsers (ID)
)
ENGINE=HEAP
MAX_ROWS = 250;

A kliens

A kliensnek először egy munkamenet azonosítót kell kérnie a getSessionId tagfüggvény meghívásával.
Második lépésben összefűzzük a titkos kulcsot a kiszolgálótól kapott sessionId-val, majd a kapott
karakterláncból egy 128 bites kivonatot képezünk MD5 titkosítással. Ebben az a jó, hogy a titkos kulcsunkat nem
küldjük el a hálózaton keresztül.

autentikacio

Figyeljük meg az XML üzeneteket. Vegyük észre, hogy a login metódus meghívása már
tartalmazza a SOAP Header elemben a munkamenet azonosítót. A getSessionId metódus ugyanis
az egyetlen metódus, amely meghívható üres SOAP Header elemmel, a többi metódus
megköveteli a sessionId jelenlétét a SOAP fejlécben.

A kiszolgáló

Kezdjük a WSDL megírásával.
A munkamenet azonosítót így deklaráltuk a WSDL fájlban:

Arra van szükségünk, hogy hozzáférjünk a SOAP üzenet fejlécében lévő sessionId elem tartalmához.
Erre konkrét példát egy előző blogbejegyzésben találunk:
"PHP SOAP kiterjesztés - SOAP Header használata".

Továbbá azt is tudnunk kell, hogy a kliens melyik metódust hívta meg.
Ezt is az XML üzenetből tudjuk kiparszolni a köv. kóddal (a lényeg az XPath kifejezés).

Ha a kliens a getSessionId tagfüggvényt hívta meg, akkor nem ellenőrizzük a sessionId jelenlétét a SOAP fejlécben.
Ellenkező esetben SOAP fault-ot dobunk, ha a sessionId hiányzik a SOAP fejlécből.

Amikor megkaptuk a sessionId-t a SOAP üzenetben, leellenőrizzük, hogy létezik-e ilyen aktív munkamenet a
WsActiveSessions adatbázis táblában. Ha igen, akkor felújítjuk a PHP sessiont a
session_id() PHP funkcióval.

Ettől a pillanattól kezdve elérhetőek a klienshez tartozó session változók is.

Leave a Reply