Problémy s autentifikací přes CURL digest v PHP 5.6.8

Zrovna jsem zjistil, že PHP ve verzi 5.6.8 pro Windows má problém se autorizovat na weby přes curl, které používají ověření pravosti přístupu digest. Přesněji po použití hlaviček generovaných Windows SSPI vráti autentifikační mechanismus za použití funkce CURL nesprávný obsah hlavičky, čímž znemožní přihlášení na daný server.

Zjednodušeně se autorizace digest provádí tak, že si nejprve ze severu vyžádáme hlavičku http code 401, jejíž obsahem jsou informace o druhu autorizace a také důležité hodnoty pro výpočet HASH hodnoty, která se pak zpět zasílá pro ověření správné autorizace. Jedním z těchto hodnot je hodnota REALM, která má být podle specifikace zaslána v druhém požadavku nezměněna, nicméně PHP tuto hodnotu zasílá v tom druhém požadavku prázdnou a vzdálený server tak nemůže autorizaci provést. Uvedu to na příkladu:

Hlavička prvního dotazu na server vypadá následovně:

HTTP/1.1 401 Unauthorized
Content-Length: 0
Server: Microsoft-IIS/8.5
WWW-Authenticate: Digest qop="auth",algorithm=MD5-sess,nonce="afdasd",charset=utf-8,realm="Digest"
X-Powered-By: ARR/2.5
Date: Thu, 25 Feb 2016 09:25:55 GMT

 

PHP v tomto případě nastaví a vypočítá příslušné hodnoty a odešle hlavičku:

GET /Feed/feedcz.xml HTTP/1.1
Authorization: Digest username="...",realm="",nonce="afdasd",uri="some.xml",cnonce="565sdf",
nc=00000001,algorithm=MD5-sess,response="25651sadf",qop="auth", ....
Host: somehost.sk
Accept: */*

Všimněte si, že hodnota realm je v tomto případě prázdná – a to je ta chyba, která zapřičiní chybnou autorizaci.

Není to ani tak chyba PHP, ale přímo modulu CURL, který tuto chybu opravuje v pozdějších verzích. Je možné, že PHP ve verzi vyšší než 5.6.8 již tímto neduchem netrpí, ale nevím. Co jsem zkoušel tak verzi PHP 5.4.36 na linuxu – tam to funguje, a poté na Windowsech až verzi PHP 7 a tam to již také funguje správně.

Jak na nedoručitlné emailové zprávy na seznamu?

Anamnéza:

Emailová služba na seznam.cz zažívá převratné změny. Pro většinu vlastníků emailových účtu jsou tyto změny ke prospěchu, avšak pro eshopy a marketingové společnosti se změny stávají noční můrou. Nejenže seznam.cz nyní umí detekovat hromadné emaily a automaticky je dává uživateli do složky “Hromadné” (jenž většina uživatelů přehlíží a newslettery tak ztrácejí význam), ale že nyní k tomu i přidali kontrolu na úrovní zabezpečeného podpisu emailů pomocí DKIM, které je nutné pro hromadné emaily mít.

To, že seznam automaticky dává emaily do složky Hromadné, může ovlivnit pouze uživatel (a to tím, že email ze složky “Hromadné” přesune do doručených a pak by i všechny ostatní emaily daného odesílatele měly automaticky padat do složky “Doručené”), tak u problém s podpisem emailu musí zajistit sám odesílatel emailu.

Hodně jsem se divil, když při posílání posledního newsletteru z e-shopu nám zpět chodily zprávy o nedoručitelnosti emailů na účty u Seznam.cz. Nejedná se přitom pouze o účty na doméně @seznam.cz, ale i jeho přidružených domén, tedy i @email.cz, @post.cz a možná i dalších. Vždy to bylo zdůvodněno tím, že Massmail (tedy hromadný email) musí být podepsán DKIMem.

1

 

Diagnóza:

Anamnézu tedy již máme, zkusíme nyní diagnostikovat a ošetřit problém posílání hromadných emailů na emailové účty seznamu. Nejprve si vysvětlíme, co ten DKIM vůbec je, k čemu se používá, a proč jej implementoval seznam.cz do svého systému.

DKIM (DomainKeys Identified Mail) je technologie, která za pomocí asymetrického šifrování dokáže zaručit, že email tímto způsobem poslaný je po své cestě v internetu nezměněn a že opravu pochází z domény, kterou má ve své hlavičce určenou. Doručovateli tedy dává jistotu, že email nebyl poslán nikým jiným, jak se obvykle u hromadných emailů stává.
Tato jistota je zabezpečena privátním klíčem, který je umístěn pouze na serveru, ze kterého jsou odesílány emaily a pak veřejným klíčem, který pro ověření používají emailoví klienti. Ten je umístěn veřejně v záznamech DNS domén.

Na straně příjemce není třeba žádných nastavení, emailoví klienti jsou na tuto technologii připraveni a díky ní taktéž upravují své spamové filtry a emaily takto podepsané vyhodnocují jako ověřené a tudíž je zde nižší (avšak ne úplná) pravděpodobnost, že email skončí ve spamové složce (nebo jej dokonce úplně smaže). Navíc, většina klientů tyto maily zvýrazňuje určitým symbolem, že jsou od prověřeného odesílatele.

Z hlediska seznam.cz je to vhodná technika pro zabezpečení uživatelských účtů před množstvím spamů, které se na ně valí.

Vyléčení:

Informace tedy již máme, nyní si řekneme, jakým způsobem DKIM ve svých odesílaných emailech aktivovat.

Jak už jsem psal, jedná se o technologii, která používá privátní a veřejné klíče. Nebudu zde popisovat, jakým způsobem vytvořit tyto klíče, to je práce serverových techniků. Nám bude stačit vědět, že pro aktivaci této technologie na svém serveru stačí uvědomit administrátory serveru. Ti na server přidají privátní klíč pro generování a Vám pošlou veřejný klíč, který se pak musí dát do DNS záznamu, přesně do do TXT záznamu, který následně může vypadat nějak takto:
domena._domainkey IN TXT “v=DKIM1; t=s; k=rsa; p=djlkaQ/563156asdkljKLKLD7mks&k0$DFASffjlkhakljsf44”

Pro většinu eshopů bude stačit, když se na serveru nastaví pouze jedna, tzv. hlavní doména, která bude svým jménem (a svými klíči) podepisovat odeslané emaily. Například u VS hostingu mi to nastavili přímo na doménu serveru (jmeno.vshosting.cz) a sami také nastavili DNS záznamy.

U tohoto nastavení přímo na doménu serveru je třeba pouze zabezpečit, že na serveru, ze kterého jsou odesílány emaily, není nějaký “záškodník” web, jehož hlavní činností bude posílat hromané SPAMy v ohromném množství na všechny možné emaily. Musíme si uvědomit, že po nastavení je jakýkoliv email, odeslaný z tohoto serveru, přesně identifikovaný a zpětně se dá dohledat, kdo, kdy a jaký web či služba email zaslala a může se klidně stát, že se tato doména objeví na blacklistu a všechny tyto emaily najednou budou označeny jako spamové.

Pro ověření funkčnosti si po aktivaci zašlete nějaký email a v hlavičce emailu uvidíte např. toto:

2

Nyní je email zabezpečený a jsme si jistí, že je to opravdu ten odesílatel, za koho se email vydává. A to je přesně to, co seznam.cz vyžaduje.

Mám sám ověřeno, neboť po aktivaci na svém serveru a po spoštění odesílání newsletteru se mi již žádné emaily nevracely. (Ano, sice asi stále padají do složky “Hromadné”, ale s tím, jak už jsem psal, může něco udělat pouze uživatel emailové schránky)

Jen pro zajímavost, v hlavičce emailu je možné si všimnout i druhého zabezpečovacího mechanismu, který standardě používám a sice SPF. Je to další technologie na ověření emailu. Není však tak bezpečná a účinná, protože jen zjišťuje přijatý email jen na základě IP adresy a nedokáže tedy garantovat integritu emailu. O této technologii se rozepíšu někdy u příštího článku.

Vhodný editor pro PHP

Každý programátor, ať již programuje v C , C++, či právě v PHP potřebuje pro svůj vývoj vhodný editor zdrojového kódu. I když pro PHP nám stačí jakýkoliv editor, který dokáže uložit čistý text, je přece jenom vhodné používat kvalitní editory, můžeme jim také říci vývojové prostředí, které dokáží zdrojový kód nejen barevně odlišit, ale také nám různými funkcemi pomáhají při např. hledání syntaktických chyb ve zdrojovém kódu. Osobně jsem měl tu možnost pracovat ve čtyřech editorech, které mohu specifikovat asi takto:

PSPad

Mé začátky v programování směřovaly k nějakému jednoduchému editoru, kterým je právě PSPad. Jedná se o rychlý, nenáročný jak na instalaci tak v používání, volně stažitelný, editor nejen PHP zdrojových kódů, ale i všech ostatních jazyků přes značkovací jazyky jako HTML, XML, až po JAVA a C/C++. Nejedná se o žádné vývojové prostředí, a proto podpora všech těchto jazyků je jen na úrovni rozpoznání zdrojového kódu a barevné odlišení funkčních příkazů od jednoduchých textů pro proměnné, navíc však umí také rozpoznávat metody a funkce jednotlivých objektů pro sestavení jednoduchého průzkumníka zdrojového kódu.
I když se jedná o v celku nenáročný editor, disponuje celkem solidní zásobou funkcí a nástrojů pro rychlou editaci textů, zarovnávání a automatického dokončování závorek, řetězců a uvozovek. Dodnes ho používám jakožto prohlížeč a pro jednoduchou úpravu všech možných textů a zdrojových kódu.
(http://www.pspad.com/)

Zend studio

Dříve bylo tohle vývojové prostředí samostatné, nyní již vychází z vývojového prostředí Eclipse, který však není volně ke stažení, ale existuje pod placenou licenci firmy Zend. Editor je plně postaven pro PHP a využívá veškeré možné funkce a nástroje pro podporu programování, lazení a spouštění PHP skriptů. Instalace programu je jednoduchá a nevyžaduje zvláštní instalaci debuggeru, tak jako je tomu u jiných editorů, ten je již totiž v rámci instalace nastaven a při spuštění skriptu plně využit.
Při psaní zdrojového kódu samozřejmě používá všechny standardní funkce, jako automatické doplňování závorek, uvozovek, barevné odlišení kódu, avšak oproti PSPadu má samozřejmě mnoho funkcí navíc, které zpříjemňují editaci programového kódu, jako např:
Code folding – jde o možnost si „zavírat“ funkce, metody a případné komentáře tak, aby zbytečně nerozptylovaly a zkrátili tak editovaný text na stránce
Oprava chyb v realtime – velice dobrá věc, kdy ihned vidíme, že jsme provedli syntatickou chybu, avšak nejen to, editor dokáže rozeznávat i chyby jako např. nedefinovaných proměnných, či proměnná není v kontextu kódu využitá a dalších.
Asistence při psaní kódu – automaticky tak napovídá a doplňuje právě psaný název funkce, proměnné,  rezervované slovo atd.
Chytré přejití na definici funkce/proměnné – automaticky lze přecházet na definici funkce, či proměnné a to i v rámci různých souborů
Automatický popis funkcí PHP – zobrazuje popis PHP funkcí při najetí kurzorem
Automatické formatování obsahu textu
Verzování kódu pomocí CVS či SVN
A mnoho dalších funkcí…

S tímto editorem jsem pracoval cca. 3 měsíce v jeho trial verzi a mohu říci že se s ním  pracuje jakž takž dobře. Avšak, nevím jestli to bylo trial verzi, kterou jsem měl k dispozici, ale mnoho těchto výše popsaných funkcí fungovalo tak na 60 %. Hodně krát se mi stávalo, že se funkce najednou nedokázaly zavřít pomocí funce Code folding, nebo naopak zase nešly otevřít. Někdy se také editor zavřel bez sebemenšího důvodu a vůbec celé prostědí mi připadalo takové nestabilní. Jelikož se jedná o licencovaný software, doufal jsem v jakousi menší chybovost programu, opak je však pravdou. Doufám, že se již Zenďáci zlepšili a nová verze již mnoho těchto chyb neobsahuje.
(http://www.zend.com/)

Eclipse

Velmi známé vývojové prostředí pro všechny platformy a snad i všechny programovací jazyky a je volně ke stažení, tedy žádné licenční poplatky jako u Zend studio. Přímo pro PHP je určen projekt Eclipse PDT, což je zkratka pro PHP Development Tools, jež je jakýsi framework pro Eclipse, který zajišťuje vše potřebné pro vývoj PHP aplikací.
Po instalaci PHP debuggeru (není součástí instalace) pak PDT nabízí prakticky stejnou funkcionalitu jako Zend studio (avšak mnohem stabilnější) plus navíc se může dále rozšiřovat o další nástroje.
(http://www.eclipse.org/)

NetBeans

Vývojové prostředí NetBeans existuje, stejně jako Eclipse, pro všechny platformy a pro řadu programovacích jazyků a je taktéž volně stažitelný bez licenčních poplatků. Funkcionalitou je shodný s výše uvedenými editory Eclipse a Zend studio, kdy jde navíc dále rozšiřovat pomocí různých doplňků.
Mezi hlavní výhody oproti konkurenci je hlavně v rychlosti. I když jsou všechny tyto vývojové prostředí naprogramovány v Java, je podle mého soudu tento editor, co se týče rychlosti zobrazení, funkcí a doplňků, nejrychlejší. Za další obsahuje již mnoho vestavěných doplňků, jako například výborný editor CSS stylů (s náhledy), HTML editor a mnoho jiných. Co se týče chybovosti, ještě se mi nestalo, že by nějaká funkce najednou nefungovala, jako se to často stávalo u Zend studia potažmo i u Eclipsu, právě naopak, vše je krásně rychle (jenž se možnosti hardwaru týče) a svižné (až na otevírání projektu, neboť si NetBeans po otevření projektu indexuje všechny soubory a tím si vytváří přístup ke všem zdrojům projektu).
(http://www.netbeans.org/)

PS: aktualizace 2015 – nyní už používám jedině PHP STORM – excelentní to editor.

Vypršení životnosti relace – vyřešení pomocí AJAX

V předchozím článku o vypršení životnosti relace jsem popisoval dvě možnosti, jak tento problém řešit. První možnost byla prodloužit životnost relace přímo v nastavení PHP, avšak tato možnost se zdá bytí neschůdná, neboť zbytečně zatěžuje server a může vést až k výpadku serveru. Druhá možnost se opírá o prodlužování relací. V této části článku vytvořím službu s využitím AJAX, která nám bude automaticky prodlužovat relace a tím uchovávat data aktivního uživatele na serveru.
Nekončící relace pomocí dvou skriptů

function sessionHolderStart()
{
 if (HTTP_PATH) url = HTTP_PATH+'session_holder.php';
 else url = '/session_holder.php';
 if (window.XMLHttpRequest) {
 self.HTTPrequest = new XMLHttpRequest();
 } else if (window.ActiveXObject) {
 try {
 self.HTTPrequest = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (eror) {
 self.HTTPrequest = new ActiveXObject("Microsoft.XMLHTTP");
 }
 }

 self.HTTPrequest.open("GET", url, true);
 self.HTTPrequest.send(null);
}
sessionHolderInterval = window.setInterval(sessionHolderStart, 10 * 60 * 1000);

Za prvé bude nutné vytvořit soubor sessionHolder.js, který obsahuje funkce pro komunikaci se serverem:

Jak vidíme, jedná se o celkem jednoduchý skript, který obsahuje funkci, pomocí níž AJAX navazuje spojení se serverem a zavolá skript session_holder.php. Tato funkce je následně předána do intervalu, který probíhá co 10 minut. Jediný zmatek v souboru může způsobovat proměnná HTTP_PATH , která je ve funkci použita. Vězte, že se jedná o proměnou, kterou standardně používám při vývoji na localhost. Jelikož na localhostu nedefinuji DOMAIN NAME pro každý projekt, tak by:

url = '/session_holder.php';

odkazoval do ROOTu neexistujícího webu/adresy. Proto si na začátku HTML definuji HTTP_PATH, který směřuje přímo do ROOTu určitého projektu.

Dále musíme vytvořit PHP skript session_holder.php, který je právě díky AJAXu volán:

<?php
session_start();
?>

kupodivu v něm volám pouze jednu funkci session_start. Pokud se podíváte na článek o vypršení životnosti relace, kde vysvětluji implementaci relací do PHP, tak je Vám zcela jasné, co daný skript provede. Ano, tento skript zaktualizuje soubor relace a tím pádem prodlouží jeho platnost a díky tomu, že je neustále volán co 10 minut, nemůže se stát, že by relace kdykoli vypršela.

Sumarizace

Díky těmto skriptům, které jsou z hlediska náročnosti na webový server velmi jednoduché, lze účelově vytvořit nikdy nekončící relaci a tím uspokojit uživatelé internetu, kteří již nebudou nadávat na samoúčelné vymazání Jejich objednávky z košíku.

Session – Vypršení životnosti relace – problém a řešení

Vypršení životnosti relace – problém a řešení

Relace („sessions“) se ve webových aplikacích používají k uchování stavu aplikace zpuštěné na webovém prohlížeči uživatele. Jelikož je HTTP protokol standardně bezstavový, tak je tímto dána možnost uchovat si na serveru určitá data, která nám pomáhají uchovat si požadavky na stránku odeslané uživatelem a při následném zobrazení stránky tyto informace použít.

Kde je problém?

Každá vytvořená relace má však svou určenou životnost. Vždy končí při zavření prohlížeče, avšak také končí při uplynutí doby, na kterou je nastavena. Ztráta relace na stránkách může být někdy nepříjemná. Pokud pomineme nepříjemné emaily od zákazníků, kterým se ztrácejí vložené produkty do košíku, jelikož si při nákupu v internetovém obchodu odskočili na oběd (čímž se po určitém čase session zneplatnila), tak velmi flustrující může být ztráta session v době, kdy například píšeme dlouhý článek přímo ve webovém editoru na určitém webu a při uložení nám server odpoví tím, že bychom se měli znovu přihlásit, čímž jsme samozřejmě přišli o celý napsaný článek (nesmějte se, tato situace se mi doopravdy stala na nějakém blogu). Jak tedy zabezpečit webové aplikace, aby se relace neztrácela?
Navýšení hodnoty životnosti relace
Jednou z možností je navýšení hodnoty životnosti relace přímo v nastavení PHP.INI (hodnota session.gc_maxlifetime). Tuto operaci však nedoporučuji a to z tohoto důvodu: Relace jako taková je vlastně soubor proměnných, případně i objektů, které jsou PHP strojem serializovány (rozuměj převedeny do stavu, kdy lze hodnoty bez obtíží uložit na disk) a uloženy do souboru adresáře relací na serveru. Jelikož je pro každého návštěvníka stránky vytvořená nová relace, tak při návštěvnosti např. 4000 lidí denně je nutno vytvořit 4000 souboru v adresáři (pokud teda nastavíme životnost na 24 hodin).  A pokud navíc na serveru provozujeme více webových aplikací a všechny tyto aplikace ukládají své relace do jediného adresáře (standardní situace), tak máme hned v adresáři několik tisícovek souborů. I selský rozum nám napovídá, že následné hledání jediného souboru v této změti souborů při načtení každé další webové stránky, nám server znatelně zpomalí ne-li přímo celý server shodí.
Druhou, a mnohem lepší možností, je vytvořit si službu, která nám bude životnost relace neustále prodlužovat.

Prodlužování relace

Pokud si přestavíme, jakým způsobem PHP pracuje s relací, tak je velmi jednoduché vytvořit si skript, který nám bude automaticky, po nějakém daném čase, životnost relace prodlužovat.

Jak už jsem psal výše, relace v PHP je serializovaný soubor, který obsahuje soubor proměnných nebo objektů, a je uložen v adresáři pro relace. Název tohoto souboru je shodný s hodnotou cookie SESID, která je zasílána v požadavku od uživatele. V PHP kódu po zavolání funkce session_start() (nebo pokud je zapnutá v PHP.INI direktiva session.auto_start)  se v adresáři pro relace začne hledat soubor s tímto názvem. Pokud je nalezený a je platný (jeho životnost ještě nevypršela), tak si jej „odserializuje“  (převede zpět do podoby proměnné či objektu) a uloží si veškerý obsah do globální proměnné SESSION. Při skončení skriptu PHP automaticky zavolá funkci session_write_close, která serializuje všechny hodnoty v proměnné SESSION a uloží je do adresáře pro relace pod názvem SESID.
Důležité je zde zmínit, že životnost se v nových verzích PHP (od verze 4.2.3) zjišťuje pomocí funkce MTIME, která vrací čas modifikace souboru (ve starších verzích se používala funkce ATIME, tedy čas, kdy byl soubor naposledy otevřen, která způsobovala problémy na systému WINDOWS, který tuto funkci nepodporoval) .
Pokud tedy víme, jak relace pracují, je možné vytvořit dva jednoduché soubory, které nám budou po určitém intervalu volat funkci session_start na serveru a tím neustále prodlužovat životnost relace.

Maskování políčka pro hesla

Našel jsem zajímavý věcičku na stránkce lab.arc90.com pro pohodlné zadávání hesel do formulářu typu „password“.

Asi každý má problém s tím, že i když zná správně heslo k přihlášení na určité stránky, tak se občas překlikne a samozřejmě pak nadává, proč se sakra pod správným heslem neumí k webu dostat. Zajímavým způsobem, jak uživateli dát vědět, že jeho heslo je nesprávně zadané, je formou různě barevného grafu spočítaného ze zadaného hesla, čímž může uživatele ihned vizuálně upozornit, že heslo, které zadává, není tím, které zde zadává normálně. Samozřejmě záleží na tom, jak často se přihlašujeme na stránky se stejným heslem a můžeme si tak zapamatovat vizuální informaci o správnosti hesla, ale i tak se jedná o opravdu pěkné zpestření.

Jedinou výtku bych snad měl pro implementaci. Utilita je vytvořena pro JavaScriptiovou knihovnu JQUERY, která již sama o sobě má nějakou tu velikost, ale k ní musí být ještě přidány další dvě knihovny, které přímo s tímto skriptem spolupracují. Jedná se o pluginy jquery.sparkline pro kreslení barevných grafů a také plugin jquery.sha1 pro výpočet hashe, ze kterého se graf provádí. Dohromady všechny tyto knihovny zabírají 200Kb, tudíž se jedná o dost velký balík na takovou blbůstku. Nicméně při dnešní rychlosti internetu by tato věc neměla moc vadit (ještě když správně používáme cache prohlížeče).
Co vy na to. Dali by jste si tuhle celkem vychytanou věc na své stránky?

AJAX

Co je AJAX

AJAX (Asynchronous JavaScript And XML) je nestandardní rozšíření skriptovacího jazyka JavaScript, který se používá v dynamicky generovaných webových aplikacích.
Jedná se o JavaScriptový objekt, s jehož pomocí je možné zasílat a přijímat z webového serveru různé formáty dat, zahrnující XML, HTML, nebo jen čistý text. Tato operace je prováděná asynchronně a tímto způsobem je možné vytvářet opravdu dynamické webové stránky, kde se obsah stránky mění jakoby v pozadí aplikace a na žádost klienta (uživatele), bez nutnosti znovu nahrávat celou stránku.

V čem je háček?

Protože je AJAX rozšířením JavaScriptu, tak je samozřejmě možné jej použít pouze u internetových prohlížečů, které jej podporují. Proto je nevhodné všechny informace na stránkách prezentovat uživatelům jen přes AJAX, jednak ne všichni uživatelé (zhruba 1% uživatelů má JavaScript deaktivovaný) a ne všechny internetové prohlížeče (hlavně internetové prohlížeče v mobilních telefonech) JavaScript podporují. Nakonec i vyhledávací roboti (jako např: googlebot, seznambot)  s JavaScriptem neumí pracovat a tedy neumí indexovat informace prezentované uživateli JavaScriptem. Proto je nutné, aby byly stránky přístupné i bez JavaScriptu a JavaScript a AJAX používat jen jakožto rozšíření stávajících stránek, poskytující uživatelům větší komfortnost a přístupnost.
Ovšem u některých projektů je AJAX přímo nutností, jako například u Google maps, či mapy seznamu. Tyto aplikace neustále komunikují se serverem a bylo by dosti obtížné tuto funkci provádět načtením stránky pokaždé, kdy uživatel změní polohu bodu na mapě.

Aplikace používající AJAX

Mimo výše uvedené aplikace pro zobrazení map, se také AJAX velmi často používá u tzv. našeptávače, který je k vidění například u vyhledávače na seznam.cz. Kdykoliv se do vyhledávacího políčka zadá vyhledávací výraz, tak se ihned aktivuje funkce, která posílá napsané znaky serveru. Ten následně pošle zpět možné klíčové slova, která zřejmě chce zřejmě uživatel do políčka zadat. Vše se tak děje na pozadí aplikace a uživatel nemá vůbec ponětí, že prohlížeč neustále komunikuje se serverem a posílají si vzájemně data.
Dalšími aplikacemi, používající AJAX, jmenujme také např. IceWarp webmail.

Implementace

Jelikož je AJAX nestandardním rozšířením, tak jej jednotlivé firmy, vytvářející internetové prohlížeče, implementovaly do JavaScriptu pod různými objekty.  Microsoft a jeho prohlížeče Internet Explorer do verze 6 používají k přístupu prvek ActiveX Objektu “Microsoft.XMLHTTP”, kdežto ostatní prohlížeče (Mozzila, Firefox, Safari, Internet Explorer 7 a vyšší) používají přímo třídu XMLHttpRequest. Jejich jedlotlivé metody jsou již shodné a proto se mohou vytvářet například tímto způsobem:

var httpRequest;
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
 httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
 httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}

Tímto je vytvořen objekt httpRequest. Následně je nutno metodou open() definovat požadavek, který má být odeslán na server. Metoda open() má tento tvar:
httpRequest.open(metoda požadavku, URL, typ požadavku);
kde jednotlivé parametry znamenají:
metoda požadavku – GET nebo POST
URL – např. “http://www.priklad.cz/ajax.php”
typ požadavku – zda se jedná o synchronní (false), nebo asynchronní (true) přenost dat

Jak už býlo uvedeno výše, AJAX je zkratou pro asynchronní přenos dat. Proto musí existovat způsob, který zajistí, že data budou odeslána na server, avšak uživatel zároveň bude moci nadále pracovat s prohlížečem, bez nutnosti čekat na výsledek odeslaný serverem. Pro tento účel je vytvořena metoda onreadystatechange, ke které je nuto přiřadit akci, která se má provést při každé změně stavu zasílání dat.
Existují celkem 4:
0: (uninitialized) dosud neinicializovano metodou send()
1: (loading) nahrává se
2: (loaded) nahráno
3: (interactive)
4: (complete)  kompletní dokončení požadavku

Stavy zasílání dat je možné získat vlastností readyState, a se spojení s metodou onreadystatechange lze přesně určit, kdy byla dat v pořádku ze serveru přijata, například takto:

httpRequest.onreadystatechange = function () {
if (httpRequest.readyState == 4) {
 // data přijata, můžu zpracovat
} else {
 // data stále nepřijata
}
}

Pokud je vytvořen objekt httpRequest a jsou definovány funkce a metody pro zasílání a přijímání dat, je možné odeslat celý požadavek na server pomocí metody send():
httpRequest.send(null);

Po úspěšném přijetí dat je možné si tato data vyzvednout metodou httpRequest.responseXML, pokud je zaslán validní XML, nebo pomocí httpRequest.responseText v jakémkoli jiném případě.

Více informací o implementaci a všech metodách objektu httpRequest je možné získat na webu Mozilla Developer Center.

Závěrem

Použití AJAXu znamená zvýšení použitelnosti a přívětivosti webových aplikací. Webové aplikace se tak přizpůsobují aplikacím desktopovým, kdy na požadavek klienta jsou data ihned k dispozici, aníž by bylo nutno načítat znova celou stránku. Tímto se taktéž zvyšuje rychlost aplikace, neboť jsou zasílány pouze ta data, která jsou v daný moment potřebná. Je však vždy nutno počítat s tím, že daná data zasílána AJAXem nejsou viditelná pro vyhledávací roboty, proto je nutno zajistit jejich nalezení i bez použití AJAXu.

A ještě úplně závěrem, tento článek jsem psal někdy v roce 2009 – dnes se už vše řeší pomocí JQUERY.

Firebug – pohodlný vývoj webových aplikací

Při vývoji webových aplikací potřebuje vývojář nástroj, který by mu pomohl interaktivně zasahovat do zobrazených stránek, měnit CSS styly či pracovat a zadávat příkazy javascriptu. Firebug je právě tímto nástrojem, který jsem si, jakož to programátor, velmi oblíbil.

Co je Firebug

Firebug je doplňek do stále oblibenějšího internetového prohlížeče Mozzily Firefox, který umožňuje interaktivně zasahovat do zobrazených stránek a měnit tak obsah stránek, grafiku v podobě CSS, či testovat Javascriptové funkce. Tímto způsobem pomáha vyvojáří nacházet chyby ve vývoji a umožňuje tyto chyby odstraňovat.

Instalace Firebugu

Firebug je určen pro Mozzila Firefox (od verze 2.0) a je možné si jej zdarma stáhnout přímo ze stránek dopňků pro firefox.

Pohled do nitra „ohnivého broučka“

Po úspěšné instalaci se v pravém dolním rohu zobrazí ikona Firebugu v podobě brouka. Firebug je standardně vypnutý (ikona nesvítí, je šedá), proto je nutné na tuto ikonu poklepat a povolit jej.  Po jeho zapnutí je možné se v okně přepínat mezi jednotlivými záložkami, kdy v každé je možné upravovat část (řekněme použitou technologii) webové stránky.

Konzole

V této záložce je možné nalézt velmi detailně zobrazené chybové zprávy JavaScriptu. Které je možné si rozkliknout a okamžitě přejít na řádek, ve které se stala chyba.  Tato konzole taktéž zobrazuje informativní zprávy celé aplikace, mimochodem se zde můžeme dočíst, že například použití nějakých funkcí javascriptu je zastaralé a nemusí fungovat na novějších prohlížečích.

Html

Zde je možné si zobrazit HTML kod stránky, který je výborně rozčleněn do jednotlivých sekcí (tágů) stránky a jednoduše si takhle procházet celý strom HTML dokumentu. Po najetí na jednotlivý prvek (tág) HTML dokumentu se na stránkách tento element barevně označí. To je velmi dobrá vlastnost, kdy je možné tímto způsobem krásně hledat chyby v zobrazování dokumentu.
Po přepnutí do režimu úprav je možné přímo zasahovat  a interaktivně upravovat HTML dokument, kdy okamžitě vydíme výsledek své práce přímo na stránkách prohlížeče.

CSS

Z názvu je patrné, že zde je možné přehledně procházet kaskádové styly zobrazeného dokumentu. Noční můra každého webového vyvojáře je umísťování jednotlivých prvků do designu celého webu. Tento nástroj tuto noční můru alespoň trošičku zahání, kdy je možné, zase interaktivně, měnit jednotlivé elementy kaskádových stylů a přitom vidět, co to udělá se stránkami.
Skripty
Záložka, která zobrazuje JavaScript, který je používán na webové stránce.  Nelze přímo skripty měnit, ale je zde možnost vytvořit zde tzv. break point, a tím pomoci při debugování skriptu, k čemuž také pomáhá levý panel, kde je možné přímo vytvářet příkazy javascriptu a ty také spuštět, přičemž si okno uchovává informace, které daná funkce, či příkaz provedl, a je možné v něm pohodlně listovat. Tak například, po zadání příkazu document.getElementsByTagName(„body“), vyběhnou všechny metody a vlastnosti pro daný element.
Síť
Záložka, ve které lze nalézt veškeré dotazy a odpovědi ze serveru v pořadí, v jakém přicházely do prohlížeče.  Je možné si každý dotaz rozkliknout a zobrazit jednotlivé hlavičky dotazu, i odpovědi. Je zde možnost kontrolovat jednotlivou odezvu ze serveru na každý požadavek prohlížeče.

Závěrem

Firebug je velice dobrým nástrojem pro každého webového vyvojáře, ve kterém je možné si  HTML dokument stránky do detailu rozpitvat, a nalézt a taktéž ihned opravit veškeré chyby, ať již chyby zobrazování, nebo chyby JavaScriptu. Jen škoda, že něco takového nefunguje pro Internet Explorer, kde dohledat se chyby JavaScriptu je složitější, než najít jehlu v kupce sena!!!

CAPTCHA

Captcha je (a co jsem hledal tak snad i jediná) vhodná technika, která dokáže odfiltrovat uživatele od automatického robota při odesílání formulářů v internetových aplikacích. Captcha se na webu liší svým zobrazením, někdy se jedná o obrázek, o zvukovou nahrávku, či otázku, na kterou je nutno odpovědět. Standardně ve svých aplikacích používám jednoduchou obrázkovou Captchu, u které jsem předpokládal, že je proti robotům neprolomitelná. Můj zjevný omyl se projevil před několika dny, kde se najednou na určitém webu v diskuzi začaly objevovat příspěvky s odkazy na „hanbaté“ stránky. Samozřejmě vím, že se spamoví roboti snaží různými technikami Captchu obejít, ovšem netušil jsem, že se tak budou snažit u okrajových webů, kde je přístupnost nějakých pár set lidí denně. Zkusím Vám tedy letmo popsat, jak jsem se Spamem bojoval a nakonec i uspěl. Snad Vám to pomůže při Vašich projektech a již nebudete zbytečně zkoušet kousky, které jsem zkoušel já.
Jak už jsem psal výše, netušil jsem, že by se spamový robot snažil prolomit Captchu na webech s přístupností do jednoho tisíce lidí denně. Proto, když začaly chodit spamové zprávy do diskuze na jednom webu, jsem si  nemohl připustit, že je to zrovna nevhodnou  obrázkovou Captchou. Na tomto webu byla implementovaná CAPTCHA, která za pomocí JavaScriptu odstraňovala nutnost uživatele vkládat požadovaný kód (psal jsem o tom v článku Používejte geniální CAPTCHA techniku), proto jsem si nejprve myslel, že daný robot umí JavaScript a tím pádem se vždy do políčka pro Captcha doplní daný kód. Trošku jsem proto upravil skript, který nyní čekal 10 sekund před vyplněním Captcha kódu do políčka. Vycházel jsem z toho, že by robota nenapadlo čekat nějakou dobu na odeslání daného formuláře. I když se zdála úvaha správná, toto opatření samozřejmě nepomohlo a Spam se i nadále objevoval ve velkém množství.
V tento moment jsem si již myslel, že „geniální CAPTCHA pomocí JavaScriptu“ je neúčinná a proto jsem JavaScriptovou funkcionalitu z webu smazal, takže tam zůstala standardní, viditelná, obrázková CAPTCHA s nutností uživatele vyplnit požadovaný kód.

Ovšem když se i třetí den objevily odkazy na „hezké holky“, má třetí a konečně správná taktika pro boj se SPAMem byla nakonec úspěšná. A to aktualizace CAPTCHA, respektive aktualizace kódu pro generování CAPTCHA obrázku, který ve výsledku vypadal pro člověka méně čitelný, přesto proti robotům velmi úspěšný. Když jsem ještě k tomu přidal JavaScriptovou funkcionalitu, dostal jsem se znovu tam, kde jsem chtěl: neotravuji uživatele vyplňováním CAPTCHA kódu do políčka a zároveň je daná ochrana (tedy prozatím) úspěšná i před útokem robotů.
Při tomto boji se SPAMem jsem se naučil pár věcí:
Žádná ochrana proti SPAMu není stoprocentní a její procentní úspěšnost při častém používání velice rychle klesá k nule.
Když už se někdo protlačil přes ochranu, vždy aktualizuj jádro problému, v tomto případě obrázek CAPTCHA

A rada na závěr: i když se Vám jako programátorovi jeví Vaše CAPTCHA jako dokonalá barikáda před útokem SPAMů, vždy ji po nějakém čase aktualizujte, neboť SPAMoví roboti „nikdy nespí“.

Bezpečnost webových aplikací

Bezpečnost webových aplikací je mnohdy podceňovaná, přitom tyto aplikace mohou sdílet velmi důvěrná data o lidech, kteří aplikace používají. Ať již se jedná jen o jména a emaily našich zákazníků, tyto informace v jistých rukách mohou představovat velmi vysoké riziko zneužití. Je nutné si uvědomit, že bez dostatečného zabezpečení těchto dat se vystavujeme riziku nejen zneužití osobních informací našich zákazníků třetími osobami, ale také znevážení našich projektů a možná i soudních žalob ze stran zákazníků o vydání důvěrných dat třetím osobám.
Množství útoků na webové servery neustále roste, přičemž se mění i taktika útočníků. Na těchto internetových stránkách představím nejznámější typy útoků a možností jejich obrany (pokud je u daného typu útoku vůbec nějaká možnost obrany).

Cross site scripting

Hojně používaná metoda útočníků, kdy pomocí JavaScriptu dokáží ovládnout celý systém webové aplikace. Tato metoda těží z nedbalosti programátorů, kteří nedokonale zabezpečili vstupy a výstupy uživatele a dovolili mu vytvořit kód JavaScriptu a ten navíc ještě na svých stránkách spustit. Útočník tak může ovládat aplikaci a vytvářet podvržené stránky nic netušícím uživatelům. Co je však ještě horší, je možné tímto způsobem zjistit SESSION ID (jedinečný identifikátor uživatele) a následně se vydávat za právoplatného uživatele. Důsledky mohou být katastrofální jak pro uživatele webové aplikace, tak i pro administrátora aplikace, jelikož není moc velký problém tímto způsobem vstoupit do administrace aplikace a provádět různé operace za administrátora.

Možnosti obrany

Je nutné si uvědomit, že veškeré vstupy uživatele mohou být potencionálně nebezpečné. Ať již se jedná o vstupy na základě formulářů zaslané metodami POST a GET, tak i vstupy, u kterých přímo není jasný původ, mezi něž zahrnujeme COOKIES, či hlavičky jednotlivých požadavků (HEAD). Vývojář proto musí veškeré vstupy uživatele kontrolovat a filtrovat na základě toho, co chce od uživatele získat. Pokud od uživatele žádáme jméno a heslo pro přihlášení, určitě mu nedovolíme, aby do políček zadal nějaký JavaScriptový kód. Pokud zadá, musí aplikace tento kód odstranit a nedovolit jeho spuštění a to například tím, že od zadaných hodnot odstraníme veškeré HTML značky (tím odstraníme i HTML značky pro uvozování JavaScriptových kódu <SCRIPT></SCRIPT> a tím znemožníme spuštění kódu) a necháme jen čistý text.
Někdy je vhodné dovolit uživateli, aby mohl zadávat i HTML značky pro například formátování textu při vkládání článků. V takovém případě musí vývojář filtrovat takové značky HTML,  které mohou být potenciálně nebezpečné. Problém je, že kromě značek <SCRIPT></SCRIPT> mohou být nebezpečné i značky, které se na první pohled jeví, jako bezpečné, např. značka <IMG>. Tato nepárová značka umožňuje vkládat obrázky do HTML stránky, avšak jako každá značka může obsahovat i vytvoření obsluhy událostí a tu navázat na JavaScriptový kód. Např. <img onload=”alert(‘ahoj’)”/> vytvoří obrázek, avšak ihned po načtení obrázku se spustí nebezpečný kód JavaScriptu (v tomto případě jen zobrazí hlášku “ahoj”).
Pro zamezení těchto neoprávněných škodlivých skriptů je nutné vytvořit filtrovací funkci, která bude procházet veškerý text od uživatele tak, jako to například dělá internetový prohlížeč, a odstraňovat nebezpečné značky, či vlastnosti značek. Problém je, že pokud uživatel zadá např. <scr<script>ipt>, tak po odstranění <skript> vznikne <skript> znovu a útočník může útočit dál. Proto je důležité procházet filtr několikrát, dokud není text od značek plně odfiltrován.

Závěrem

Není přímo jednoduché se bránit cross site scriptingu. Ovšem vývojář musí udělat vše proto, aby se útočník nemohl dostat k citlivým údajům uložených na serveru. Je proto nutné řádně kontrolovat a filtrovat veškeré požadavky přicházející od uživatele a předkládat mu stránky bezpečné stránky bez cizího skriptu.

←Older