Fyrir reyndan forritara er þessi texti kannski alls ekki óvæntur, en mér finnst margir greinar sem ég hef lesið um CORS-uppsetningu í Rails segja eitthvað á borð við: nota rack-cors, leyfa hvaða gestgjafa sem er aðgang að API-inu, og (valkvætt): þú ættir að íhuga eitthvað annað (en að leyfa hvaða gestgjafa sem er) í framleiðslu.
Tillaga kóði var alltaf nálægt þeim neðri:
config/upphafskerfi/cors.rb
Relsar.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins ''
resource '', headers: :any, methods: :any
end
end
og því miður voru þessar texta varla að útskýra fyrir okkur Hvað eigi í raun að gera í framleiðslu.
Mér er nokkuð í lagi með að afrita og líma (Ég er stundum að grínast með að fyrirtæki gætu ráðið Stack Overflow-afritara.), að því marki sem er “hugsa og stilla” augnablik á milli “afrita” og “limir inn”. Svo langar mig að útskýra aðeins nánar hvað við erum að gera hér og hvernig þetta virkar í raunveruleikanum.
Ég vona að þér sé ekki illa við að ég byrji á stuttri kynningu á heiðurskenningunni og fari svo yfir Rails-dæmin.
Inngangur
Við skulum byrja frá byrjun. Til að útskýra hlutina betur hef ég skipt innganginum í þrjá hluta. Fyrsti hlutinn mun draga saman hvað uppruni er – lykilhugtakið sem við erum að ræða hér. Annar hlutinn fjallar um SOP, bara stutt lýsing. Og síðasti hlutinn fjallar um CORS sjálft sig.
Hvað er uppruni?
Samkvæmt MDN Vefur Skjöl:
– Uppruni vefefnis er skilgreindur af kerfinu (samskiptareglunni), gestgjafanum (lénið) og portinu í vefslóðinni sem notað er til að nálgast það. Tveir hlutir hafa sama uppruna aðeins þegar kerfið, gestgjafinn og portið passa saman (uppspretta)
Það virðist nokkuð skýrt, er það ekki? Skoðum tvö dæmi úr MDN, bara til öryggis.
http://example.com/app1/index.html, http://example.com/app2/index.html
Þessir tveir hér að ofan eiga sama uppruna vegna:
- áætlanir þeirra (http) eru þær sömu,
- Lén þeirra (example.com) eru sömu,
- Hafnir þeirra (ímplísítt) eru þær sömu.
http://www.example.com, http://myapp.example.com
Þessir tveir hafa mismunandi uppruna vegna lénanna (www.example.com, forrit.dæmi.com) eru mismunandi.
Ég vona að þetta sé nægilega skýrt. Ef ekki, vinsamlegast farðu á MDN vefhandbókina til að sjá fleiri dæmi.
Hvað er SOP?
MDN Web Docs segir (uppspretta):
– Reglan um sama uppruna er mikilvægt öryggisráð sem takmarkar hvernig skjal eða handrit hlaðið úr einum uppruna getur átt samskipti við auðlind úr öðrum uppruna. Hún hjálpar til við að einangra hugsanlega spillandi skjöl og dregur úr mögulegum árásarvettvangi.
– Skrifanir frá öðrum uppruna eru yfirleitt leyfðar. Dæmi eru tenglar, endurbeiningar og eyðublaðssendingar.
– Innlimun frá öðrum uppruna er yfirleitt leyfð.
– Lestraraðgangur yfir uppruna er venjulega bannaður, en hann lekur oft vegna innlimunar.
Notaðu CORS að leyfa aðgang þvert á uppruna
Jæja, eins og þú sérð er mikið um þvert-upprunahegðun í skilgreiningum SOP. Það er í lagi. Allt sem við þurfum að vita núna er að sami uppruni hefur meiri heimildir og við getum rýmkað reglurnar um þvert-uppruna með því að nota CORS. Og hér kemur næsti kafli inn.
Hvað er CORS?
Miðað við orð MDN:
- Cross-Origin Resource Sharing (CORS) er HTTP-hausamiðað kerfi sem gerir þjónustunni kleift að tilgreina hvaða aðrar uppruna (lén, skema eða höfn) en eigin sem vafrinn á að leyfa hleðslu auðlinda frá. CORS byggir einnig á kerfi þar sem vafrar senda “forflugsbeiðni” (preflight) til netþjónsins sem hýsir auðlindina frá öðru uppruna, til að athuga hvort netþjónninn leyfi raunverulegu beiðnina. Í þeirri forflugsbeiðni sendir vafrinn hausa sem tilgreina HTTP-aðferðina og þá hausa sem notaðir verða í raunverulegu beiðninni. (uppspretta).
Það er samt ekki nóg. Það sem þar var ekki sagt skýrt er að mikilvægasta hausið þegar notað er CORS er Aðgangsstýring-leyfir-uppruna:
- Þeir
Aðgangsstýring-leyfir-uppruna Svarshausinn gefur til kynna hvort svarið megi deila með kóðann sem sendi beiðnina frá tilgreindum uppruna (uppspretta).
Jæja, þetta ætti að vera það. Í raunveruleikanum, þegar verið er að stilla CORS, við stillum venjulega ACAO Fyrst hausinn.
Raunlíf
Þetta er allt varðandi skilgreiningar. Skulum snúa aftur að Rails og dæmum úr raunlífi.
Hvernig á að stilla CORS í Rails?
Við munum örugglega nota rack-cors (eins og okkur var sagt). Við skulum rifja upp fyrsta brotið, það sem oftast er birt í öðrum greinum:
config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins ''
resource '', headers: :any, methods: :any
end
end
Fjöldi valkosta er gríðarlegur eða jafnvel óendanlegur, en skulum íhuga þessa tvo:
- Við erum að byggja forritaskil sem þriðja aðila vafraviðskiptavinum er heimilt að nota,
- Við höfum hefðbundna aðskilnað framsíðu og bakenda og viljum leyfa traustum viðskiptavinum okkar aðgang að API-inu.
API-bygging sem þriðju aðila viðskiptavinir hafa aðgang að
Ef þú stendur frammi fyrir fyrstu valkostinum gætirðu líklega valið uppruna ‘*’ – þú vilt að aðrir byggji upp viðskiptavin yfir API-inu þínu og veist ekki hverjir þeir eru, er það ekki?
Venjuleg skilvirkjun framsíðu og bakenda
Ef þú ert að þróa hið síðara, viltu líklega ekki að allir geri beiðnir yfir uppruna til API-sins þíns. Þú vilt heldur:
- leyfa framleiðsluklientum aðgang að framleiðslu-API,
- sama gildir um sviðun,
- sama gildir um localhost,
- Þú gætir viljað leyfa FE-skoðunarforritum aðgang að undirumhverfi.
Við munum enn nota rack-cors (eins og okkur var sagt að gera) – en á okkar hátt.
Skoðum að nota tvær ENV-breytur: Leyfilegar upprunaheimildir fyrir bókstaflegar upprunatilvísanir (stjörnumerki eða raunverulegur vefslóði) og Leyfilegar uppruna-regex-sniðmát fyrir mynstrin.
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)
resource '*',
methods: %i[get post put patch delete options head],
headers: :any
end
end
Hvað er að gerast hér?
- Eins og þú sérð erum við að skipta gildunum sem skilgreind eru í umhverfibreytum með mismunandi skilmerkjum. Það er vegna þess að semíkólon er ólíklegra að finnast í URL-mynstrinu.
- Bókstafleg gildi eru tilbúin til notkunar, en við verðum að kortleggja mynstur sem raunverulegar Regexp-tilvik.
- Síðan sameinum við allt saman og leyfum þessum gestgjafum aðgang að hvaða auðlind sem er með þeim leyfilegu aðferðum sem API-ið okkar notar.
Þetta ætti að veita þér næga sveigjanleika til að skilgreina viðeigandi gildi í þróunar-, undirbúnings- og framleiðsluumhverfum þínum.
Ályktanir
Látum okkur draga allt hér að ofan saman í lykilatriðum:
- Notaðu ENV-breytur til að stilla
CORS,
- Notaðu reglubundnar setningar til að leyfa mismunandi uppruna aðgang að staging-API-inu (t.d. fyrir umsóknarforrit).,
- Settu alltaf “hugsa og stilla” á milli “afrita” og “limir inn”.
Þetta er það. Áttu góðan dag! 🙂
Lesa meira:
Af hverju ættir þú (líklega) að nota TypeScript?
10 nýsköpunarfyrirtæki í New York sem vert er að nefna árið 2021