Kogenud arendaja jaoks ei pruugi see tekst olla üldse üllatav, kuid ma arvan, et paljud artiklid, mida ma olen lugenud CORS-i seadistamise kohta Railsis, ütlesid midagi sellist: kasutage rack-cors, lubage igal hostil API-le ligipääsu ja (valikuliselt): tootmises peaksite kaaluma midagi muud (kui lubada igal hostil).
Kavandatud kood oli alati lähedal sellele, mis oli allpool:
config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins ''
resource '', headers: :any, methods: :any
end
end
ja kahjuks ei selgitanud need tekstid meile peaaegu üldse, mida tegelikult tootmises teha.
Ma olen üsna OK copy-paste (Ma mõnikord naljatan, et ettevõtted võiksid palgata Stack Overflow'i kopeerijat), kuivõrd "kopeerimise" ja "kleepimise" vahel on "mõtle ja kohenda" hetk. Niisiis, ma tahaksin veidi täpsustada, mida me siin teeme ja kuidas see reaalselt toimib.
Ma loodan, et te ei pane pahaks, et alustan lühikese sissejuhatusega au teooriasse ja seejärel liigun edasi Railsi näidete juurde.
Sissejuhatus
Alustame algusest. Asjade paremaks selgitamiseks olen sissejuhatuse jaotanud kolmeks osaks. Esimeses osas kirjeldatakse, mis on päritolu - võtmetermin selle kohta, mida me siin arutame. Teine osa käsitleb SOPi, lihtsalt lühikirjeldus. Ja viimane osa räägib CORS
ise.
Mis on päritolu?
Vastavalt MDN Web Docs:
- Veebisisu päritolu määratakse kindlaks URL-i skeemi (protokolli), hosti (domeeni) ja pordi järgi, mida kasutatakse sellele juurdepääsuks. Kahel objektil on sama päritolu ainult siis, kui skeem, host ja port on kõik ühesugused (allikas)
See tundub üsna selge, kas pole? Analüüsime igaks juhuks kaks näidet MDNist.
http://example.com/app1/index.html
, http://example.com/app2/index.html
Eespool nimetatud 2 on sama päritolu, sest:
- nende skeemid (http) on samad,
- nende domeenid (näiteks.com) on samad,
- nende sadamad (kaudsed) on samad.
http://www.example.com
, http://myapp.example.com
Need 2 on erineva päritoluga, sest domeenid (www.example.com
, myapp.example.com
) on erinevad.
Ma loodan, et see on piisavalt selge. Kui mitte, siis palun vaadake MDNi veebidokumente, et leida rohkem näiteid.
Mis on SOP?
MDN veebidokumendid ütlevad (allikas):
- Sama päritolu poliitika on oluline turvamehhanism, mis piirab seda, kuidas ühest allikast laetud dokument või skript saab suhelda teise päritolu ressursiga. See aitab isoleerida potentsiaalselt pahatahtlikke dokumente, vähendades võimalikke ründevektoreid.
- Päritoluülene kirjutamine on tavaliselt lubatud. Näited on lingid, ümbersuunamised ja vormide sisestamine.
- Päritoluülene varjamine on tavaliselt lubatud.
- Päritoluülene lugemine on tavaliselt keelatud, kuid lugemisjuurdepääs lekib sageli varjamise teel.
Kasutage CORS
võimaldada päritoluriigiülest juurdepääsu
Noh, nagu näete, on SOPi määratlustes palju päritoluriigiülese käitumise kohta. See on okei. Kõik, mida me peaksime nüüd teadma, on see, et samal päritolul on rohkem privileege ja me saame CORSi abil lõdvendada päritoluristide vahelisi reegleid. Ja siinkohal tuleb järgmine lõik.
Mis on CORS?
MDNi sõnadele tuginedes:
- CORS (Cross-Origin Resource Sharing) on HTTP-pealkirjal põhinev mehhanism, mis võimaldab serveril näidata mis tahes muud päritolu (domeen, skeem või port) kui tema enda, millest brauser peaks lubama ressursside laadimist. CORS tugineb ka mehhanismile, mille abil brauserid esitavad ristpäritolu ressurssi haldavale serverile "eelpäringu", et kontrollida, kas server lubab tegelikku päringut. Selle eelkontrolli käigus saadab brauser päised, mis näitavad HTTP-meetodit ja päiseid, mida kasutatakse tegelikus taotluses. (allikas).
Sellest ei piisa veel. Mida seal ei öeldud selgesõnaliselt, on see, et kõige tähtsam päis, kui kasutatakse CORS
on Access-Control-Allow-Origin
:
- The
Access-Control-Allow-Origin
response header näitab, kas vastust saab jagada antud päritoluga taotleva koodiga (allikas).
Noh, see peaks olema kõik. Reaalses elus, kui konfigureerite CORS
, konfigureerime tavaliselt ACAO
pealkiri kõigepealt.
Reaalne elu
See ongi kõik, kui tegemist on mõistetega. Pöördume tagasi Railsi ja reaalsete näidete juurde.
Kuidas konfigureerida CORS-i Railsis?
Me kasutame kindlasti rack-cors'e (nagu meile öeldi). Tuletame meelde esimest lõiku, mida teistes artiklites kõige sagedamini esitatakse:
config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins ''
resource '', headers: :any, methods: :any
end
end
Võimaluste arv on suur või isegi lõputu, kuid vaatleme neid kahte:
- me ehitame API, mida on lubatud kasutada kolmandate osapoolte brauseriklientidel,
- meil on tüüpiline frontend/backend eraldamine ja me tahame lubada oma usaldusväärsetele klientidele juurdepääsu API-le.
Ehitus API, millele pääsevad ligi kolmanda osapoole kliendid
Kui te seisate silmitsi esimese võimalusega, siis võiksite tõenäoliselt minna päritolu
'*' - sa tahad, et teised ehitaksid kliendi sinu API peal ja sa ei tea, kes nad on, eks?
Tüüpiline frontend/backend eraldamine
Kui te arendate viimast, ei soovi te tõenäoliselt, et kõik teeksid teie API-le päringupäringuid. Pigem soovite seda:
- lubada tootmisklientidele juurdepääsu tootmis-API-le,
- sama kehtib ka lavastamise kohta,
- sama kehtib ka localhosti kohta,
- võite lubada FE läbivaatuse rakendustele juurdepääsu staažile.
Me kasutame endiselt rack-korset (nagu meile öeldi) - aga meie moodi.
Kasutame 2 ENV-muutujat: ALLOWED_ORIGINS
sõna-sõnalise päritolu määratluste puhul (tärn või tegelik URL) ja LUBATUD_PÄRITOLU_REGEXPS
mustrite jaoks.
config/initializers/cors.rb
frozenstringliteral: true
toregexp = ->(string) { Regexp.new(string) }
hosts = [
*ENV.fetch('ALLOWEDORIGINS').split(','),
*ENV.fetch('ALLOWEDORIGINREGEXPS').split(';').map(&to_regexp)
]
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins(*hosts)
ressurss '*',
methods: %i[get post put patch delete options head],
headers: :any
end
end
Mis siin toimub?
- Nagu näete, jagame ENV-muutujates määratletud väärtused erinevate eraldusmärkidega. Seda seetõttu, et semikoolon esineb URL-i määratlevas mustris harvemini.
- Literaalsed väärtused on valmis kasutamiseks, kuid me peame kaardistama mustrid tegelikeks Regexp-eksemplarideks.
- Seejärel ühendame kõik kokku ja lubame nendele hostidele juurdepääsu kõikidele ressurssidele, mille meetodid on valges nimekirjas, mida meie API kasutab.
See peaks andma teile piisavalt paindlikkust, et määratleda õiged väärtused teie arendus-, staging- ja tootmiskeskkondades.
Järeldused
Võtame kõik eelnev kokku põhipunktides:
- kasutada ENV muutujaid, et konfigureerida
CORS
,
- kasutada regulaarseid väljendeid, et võimaldada erinevatele allikatele juurdepääsu staging API-le (nt läbivaatuse rakenduste jaoks),
- pane alati "mõtle ja kohenda" "kopeeri" ja "kleebi" vahele.
See on kõik. Ilusat päeva! 🙂
Loe edasi:
Miks peaksite (tõenäoliselt) kasutama Typescripti?
10 mainimist väärivat NYC Startup'i 2021. aastal