Žymės įrašai

Vasaris15

Užklausos tarp skirtingų domenų (Komentarai 423)

Žymės: saugumas,ajax,http,xmlhttprequest,flash,cookies,jsonp,proxy

Pasidalink!

AJAX

XMLHttpRequest (AJAX) užklausos

Naršyklės įprastai neleidžia daryti XMLHttpRequest (liaudyje labiau žinomo kaip AJAX) užklausų į kitą domeną, kadangi tai neatitinka Same Origin Policy saugumo koncepcijos.

Firefox 3.5 ir Safari 4 buvo įdiegta naujai sukurta naršyklių technologija CORS (cross-origin resource sharing), kuri leidžia daryti XMLHttpRequest užklausas į kitus domenus, kai šie patvirtina, jog leidžia konkretiems šaltiniams daryti užklausas.

Kaip tai veikia?

Vartotojo naršyklė, siųsdama XMLHttpRequest užklausą į kitą domeną, siunčia HTTP request header'į Origin su savo domeno reikšme.

Serveris siunčia atsakymą su HTTP response header'iu Access-Control-Allow-Origin su konkretaus domeno, kuriam leidžiama daryti užklausas, reikšme, arba * reikšme, kuri leidžia visiems šaltiniams daryti užklausas. HTTP response headerio formavimo pavyzdžiai PHP kalba:

header('Access-Control-Allow-Origin: http://www.domenas.tld');

header('Access-Control-Allow-Origin: *');

Šiuos header'ius taip pat gali siųsti ir pats HTTP serveris, pvz.: Apache, naudojant mod_headers modulį.

Daugeliu atveju to turėtų pakakti, tačiau CORS specifikacija leidžia daryti sudėtingesnes užklausas, nurodant leidžiamą HTTP metodą, atitinkamus header'ius ir kt., pvz.:

HTTP request header'iai:

Origin: http://www.domenas.tld
Access-Control-Request-Method: POST
Access-Control-Request-Headers: belekoks-headeris

HTTP response header'iai

Access-Control-Allow-Origin: http://www.domenas.tld
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: belekoks-headeris
Access-Control-Max-Age: 1728000

Tam tikrais atvejais reikia nurodyti HTTP response header'į, leidžiantį XMLHttpRequest užklausas:

Access-Control-Allow-Headers: X-Requested-With

JSONP

Kitas būdas, norint gauti ir apdoroti duomenis yra naudoti <script> elementus, kadangi jiems negalioja Same Origin Policy, pvz.:

<script type="text/javascript" src="http://kitas-domenas.tld/skriptas.php?parametras=reiksme"></script>

Tačiau kadangi šis skriptas bus iškart įvykdytas, vien duomenų pasiimti nepavyks. Dėl to, skriptas turi grąžinti kvietimą į funkciją, kuri apdoros duomenis. Pvz. šiuo atveju skriptas.php turėtų grąžinti tokį rezultatą:

funkcija({"jsonDuomenuStruktura": "reiksme"});

Čia funkcija - Javascript funkcija, kuri apdoroja gautus duomenis.

Šis metodas vadinamas JSONP (JSON with prefix).

Akivaizdu, kad šiuo metodu galima gauti ir perduoti duomenis tik GET metodu. Be to, serveris, kuris grąžina rezultatus turi būti pritaikytas JSONP duomenų perdavimui, t.y. turi būti galimybė parametrais nurodyti funkciją, kuri bus iškviečiama.

Taip pat, kadangi įterpiamas svetimas Javascript kodas, atsiranda galimų saugumo spragų, nes skriptas gali įrašyti bet kokį HTML kodą ir kitaip manipuliuoti turiniu, be to atsiranda galimybė perimti duomenis naudojant CSRF pažeidžiamumą.

Vietinis proxy

Dar vienas metodas yra naudoti skriptą tame pačiame domene, kuris serverio (ne naršyklės) lygyje padarytų HTTP užklausą į kitą domeną ir grąžintų rezultatus, pvz.: failas proxy.php, esantis tame pačiame domene:

<?php
echo file_get_contents('http://kitas-domenas.tld/skriptas.php'); // Geriau naudoti cURL

Tokiu atveju pakaks daryti užklausą į tame pačiame domene esantį proxy.php ir taip patenkinti Same Origin Policy saugumo koncepciją.

Adobe Flash užklausos

Adobe Flash elementai, darydami užklausą į kitą serverį (pvz.: norėdami pasiimti tam tikrus duomenis), kreipiasi į tame domene esantį crossdomain.xml failą (pvz.: http://www.domenas.tld/crossdomain.xml), kuriame aprašomos taisyklės, nurodančios, kokiems šaltiniams leidžiama skaityti duomenis iš serverio.

crossdomain.xml failo pavyzdys:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
    <allow-access-from domain="*"/>
    <allow-http-request-headers-from domain="*" headers="X-Requested-With"/>
</cross-domain-policy>

Verta pastebėti, jog darydamas užklausas, Flash neperduoda slapukų (pvz.: sesijos identifikatorių), todėl juos perduoti reikia kaip atskirus Flash parametrus.

Bonus tip: HTTP headeris Content-disposition

Pavyzdys: failas http://www.domenas.tld/paveikslelis.php generuoja paveikslėlį, tačiau norint jį išsaugoti, siūlomas failo vardas bus paveikslelis.php.

Norint jį pakeisti, galime siųsti HTTP response header'į:

Content-disposition: inline; filename="grazus-pavasaris.jpg"

Jei norime iškart iškviesti failo išsaugojimo langą, galime nurodyti:

Content-disposition: attachment; filename="grazus-pavasaris.jpg"

« 1 »

Žymės RSS Žymės RSS