Tilgangskontroll-tillat-opprinnelseshode forklart - med et CORS-eksempel

Ofte når du ringer til et API, kan du se en feil i konsollen som ser slik ut:

 Access to fetch at '//somesite.com' from origin '//yoursite.com' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value that is not equal to the supplied origin 

I dette innlegget skal vi lære hvorfor denne feilen skjer og hvordan du kan fikse den.

Hva er Access-Control-Allow-Originoverskriften?

Access-Control-Allow-Originer en CORS-topptekst. CORS, eller Cross Origin Resource Sharing, er en mekanisme for nettlesere som lar et nettsted som kjører ved opprinnelse A be om ressurser fra opprinnelse B.

Opprinnelse er ikke bare vertsnavnet, men en kombinasjon av port, vertsnavn og oppsett, for eksempel - //mysite.example.com:8080/

Her er et eksempel på hvor dette kommer til handling -

  1. Jeg har en opprinnelse A: //mysite.comog jeg ønsker å få ressurser fra opprinnelse B: //yoursite.com.
  2. For å beskytte sikkerheten din, vil nettleseren ikke la meg få tilgang til ressurser fra yoursite.com, og vil blokkere forespørselen min.
  3. For å tillate opprinnelse A å få tilgang til ressursene dine, må opprinnelsen B din fortelle nettleseren at det er greit for meg å få ressurser fra opprinnelsen.

Her er et eksempel fra Mozilla Developer Network som forklarer dette veldig bra:

Ved hjelp av CORS tillater nettlesere opprinnelse å dele ressurser mellom hverandre.

Det er noen overskrifter som tillater deling av ressurser på tvers av opprinnelse, men den viktigste er Access-Control-Allow-Origin. Dette forteller nettleseren hvilken opprinnelse som er tillatt å motta forespørsler fra denne serveren.

Hvem trenger å sette Access-Control-Allow-Origin?

For å forstå hvem som trenger å sette denne overskriften, bør du vurdere dette scenariet: Du surfer på et nettsted som brukes til å se og lytte til sanger. Nettstedet prøver å opprette en forbindelse til banken din i bakgrunnen skadelig.

Så hvem har den ultimate evnen til å forhindre at dette ondsinnede nettstedet stjeler dataene dine fra banken? Banken! Så banken må beskytte ressursene sine ved å sette Access-Control-Allow-Origintoppteksten som en del av svaret.

Bare husk: opprinnelsen som er ansvarlig for å betjene ressurser, må sette denne overskriften.

Hvordan bruke og når du skal passere denne overskriften

Her er et eksempel på verdier du kan angi:

  1. Access-Control-Allow-Origin : * : Tillater hvilken som helst opprinnelse.
  2. Access-Control-Allow-Origin : //mysite.com : Tillat forespørsler bare fra mysite.com.

Se det i aksjon

La oss se på et eksempel. Du kan sjekke ut denne koden på GitHub-repoen min.

Vi skal bygge en server på opprinnelse A //localhost:8000som vil sende en streng Hellos til et apiendepunkt. Vi skal ringe med dette endepunktet ved å opprette en klient på opprinnelse B //localhost:3000og deretter bruke hente for å be om ressursen. Vi forventer å se strengen Hellosendt av opprinnelse A i nettleserkonsollen med opprinnelse B.

La oss si at vi har en opprinnelse //localhost:8000som tjener denne ressursen på /apiendepunktet. Serveren sender et svar med overskriften Access-Control-Allow-Origin.

const express = require("express"); const app = express(); const port = process.env.SERVER_PORT || 8000; // Add Access Control Allow Origin headers app.use((req, res, next) => { res.setHeader("Access-Control-Allow-Origin", "//yoursite.com"); res.header( "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept" ); next(); }); app.get("/api", (req, res) => { res.json("Hello"); }); app.listen(port, () => console.log(`Listening on port ${port}`)); 

På klientsiden kan du ringe dette endepunktet ved å ringe fetchslik:

fetch('//localhost:8000/api') .then(res => res.json()) .then(res => console.log(res)); 

Åpne nå nettleserkonsollen for å se resultatet.

Siden overskriften for øyeblikket er innstilt på å tillate tilgang bare fra //yoursite.com, vil nettleseren blokkere tilgangen til ressursen, og du vil se en feil i konsollen.

For å fikse dette, endre topptekstene til dette:

 res.setHeader("Access-Control-Allow-Origin", "*"); 

Sjekk nettleserkonsollen din, og nå kan du se strengen Hello.

Interessert i flere opplæringsprogrammer og JSBytes fra meg? Registrer deg for nyhetsbrevet mitt.