V prvním dílu totoho seriálu jsme se seznámili s účelem Azure Mobile Services (vyzkoušejte zdarma!) a některými základními fakty. Ve druhém díle jsme poznali datové služby, které nám umožňují ukládat a spravovat data na serveru. Dnes se podíváme na to, jak tato data zabezpečit.
Veškerý přístup k datům se děje prostřednictvím HTTP(S) rozhraní typu REST. Každá operace na tomto rozhraním (Read, Insert, Update, Delete) má nastavení úrovně zabezpečení odděleně:
K dispozici jsou 4 úrovně zabezpečení:
Pokud chcete zpřístupňovat data aplikace selektivně v závislosti na uživateli zařízení, musíte uživatele autentizovat. Buď můžete použít nějaké svoje vlastní autenizační údaje – typicky jméno a heslo, které uživatel vzápětí zapomene a založí si jiné. Anebo můžete využít toho, že uživatel již svoji identitu má (Facebook profil, Twitter, LiveID/Microsoft Account, Google ID apod.). Druhá varianta vypadá lákavě, ale je poměrně složitá na ruční implementaci. Mobile Services ale vše zařídí za vás – podporují přitom všechny uživatele identity uvedené v závorce výše.
Pokud chcete tyto poskytovatele identit použít ve vaší aplikaci, je nutno přejít na stránky poskytovatele identity a zaregistrovat si u nich vaši mobilní aplikaci. Postup pro jednotlivé poskytovatele identity je popsán zde:
Princip je ovšem vždy stejný – od poskytovatele identity získáte identifikátor své aplikace a klíč, kterým bude zašifrován vydávaný aplikační token. Tyto údaje je poté nutno přepsat do konfigurace na portálu:
Při autentizaci vaší aplikace je pak uživatel přesměrován na stránku příslušného poskytovatele identity, přičemž v hlavičkách požadavku je předán identifikátor vaší aplikace. Po úspěšné autentizaci vrátí poskytovatel identity v HTTP odpovědi autentizační token (OAuth token) zašifrovaný klíčem vaší aplikace. Tento je poté aplikací předán službě Mobile Service, která token rozšifruje a tím ověří jeho správnost a uživatele autentizuje.
Zapojení autentizace do vaší aplikace je velmi jednoduché. Základní třída MobileService nabízí následujícím metody:
Nejčastěji budete používat metodu LoginAsync, její volání je opravdu triviální.
C# pro Windows Phone 8 a Windows Store:
await service.LoginAsync(MobileServiceAuthenticationProvider.Facebook);
JavaScript pro Windows Store:
service.login("facebook").done(function (results) {…libovolny…kod…});
JavaScript pro HTML v prohlížeči:
service.login("facebook").then(function (results) {…libovolny…kod…});
Objective C pro iOS aplikace:
[self.service.client loginViewControllerWithProvider:@"facebook" completion:^(MSUser *user, NSError *error) {…libovolny…kod…}]
Java pro Android aplikace:
service.login( MobileServiceAuthenticationProvider.Facebook, new UserAuthenticationCallback() { … });
Výsledek v aplikaci je samozřejmě závislý na použité platformě a poskytovateli autentizace. Na příkladech níže vidíte použití Google ID ve Windows Store aplikaci a Microsoft Account ve Windows Phone aplikaci:
Služba sama o sobě žádnou autorizaci uživatelů nenabízí. Umožňuje pouze autentizaci uživatele na úrovni HTTP volání a poté předá autentizační údaje serverovému skriptu obsluhujícímu příslušný požadavek. Přidat autorizaci – tedy kontrolu toho, co přesně který uživatel smí a nesmí, je potom věcí vašeho kódu. Objekt typu User nabízí dva základní údaje pro vaši aplikaci:
Pokud bychom například chtěli, aby naši aplikaci s knihami používalo více uživatelů, je to poměrně snadné. Stačí nastavit serverový Insert skript pro naši aplikaci tak, aby ukládal též identitu uživatele (příslušný sloupeček v tabulce se vytvoří automaticky, pokud máme povolené dynamické schéma):
function insert(item, user, request) { item.userId = user.userId; request.execute(); }
Pak je samozřejmě nutné omezit rozsah vracených záznamů v operaci Read:
function read(query, user, request) { query.where({ userId: user.userId }); request.execute(); }
V operaci Update pak nepovolíme manipulaci s cizími záznamy (zde je to trochu složitější, neboť musíme vyhledat v databázi aktuálního vlastníka záznamu a porovnat ho s přistupujícím uživatelem):
function update(item, user, request) { var table = tables.getTable('kniha'); table.where({ id: item.id }).read({ success: function(results) { if(results[0].userId !== user.userId) request.respond(statusCodes.FORBIDDEN, 'You may only update your records.'); else request.execute(); } }); }
Analogicky zabezpečíme též autorizaci pro operaci Delete:
function del(id, user, request) { var table = tables.getTable('kniha'); table.where({ id: id }).read({ success: function(results) { if(results[0].userId !== user.userId) request.respond(statusCodes.FORBIDDEN, 'You may only delete your records.'); else request.execute(); } }); }
A máme pro dnešek hotovo.
V posledním 4.dílu se budeme věnovat notifikačním službám.
Michael