Suomi

Paljasta CORSin (Cross-Origin Resource Sharing) salaisuudet ja opi mahdollistamaan verkkotunnusten väliset pyynnöt turvallisesti. Kattava opas kattaa kaiken perusteista edistyneisiin asetuksiin, varmistaen saumattoman ja turvallisen viestinnän.

CORSin mysteerit avattuna: Kattava opas Cross-Origin Resource Sharingiin

Nykypäivän verkottuneessa webissä sovellusten on usein käytettävä resursseja eri alkuperistä. Tässä Cross-Origin Resource Sharing (CORS) astuu kuvaan. CORS on olennainen turvallisuusmekanismi, joka säätelee, miten verkkoselaimet käsittelevät pyyntöjä yhdestä alkuperästä (verkkotunnus, protokolla ja portti) toiseen. CORSin ymmärtäminen on välttämätöntä jokaiselle web-kehittäjälle turvallisten ja toimivien verkkosovellusten rakentamiseksi.

Mikä on Same-Origin-käytäntö?

Ennen kuin sukellamme CORSiin, on tärkeää ymmärtää Same-Origin-käytäntö (SOP). SOP on verkkoselaimiin toteutettu perustavanlaatuinen turvallisuusmekanismi. Sen tarkoituksena on estää yhdellä verkkosivustolla olevia haitallisia skriptejä pääsemästä käsiksi arkaluontoisiin tietoihin toisella verkkosivustolla. Alkuperä (origin) määritellään protokollan (esim. HTTP tai HTTPS), verkkotunnuksen (esim. example.com) ja porttinumeron (esim. 80 tai 443) yhdistelmällä. Kahden URL-osoitteen katsotaan olevan samasta alkuperästä, jos niillä on sama protokolla, verkkotunnus ja portti.

Esimerkki:

SOP rajoittaa skriptien pääsyä eri alkuperästä peräisin oleviin resursseihin, ellei sen sallimiseksi ole käytössä erityisiä toimenpiteitä, kuten CORSia.

Miksi CORS on välttämätön?

Vaikka Same-Origin-käytäntö on elintärkeä turvallisuuden kannalta, se voi olla myös rajoittava. Monet nykyaikaiset verkkosovellukset tukeutuvat tietojen hakemiseen eri palvelimilta, kuten API-rajapinnoista tai sisällönjakeluverkoista (CDN). CORS tarjoaa hallitun tavan höllentää SOP-käytäntöä ja sallia lailliset alkuperien väliset pyynnöt turvallisuutta vaarantamatta.

Kuvitellaan tilanne, jossa osoitteessa http://example.com isännöity verkkosovellus tarvitsee tietoja API-palvelimelta, joka sijaitsee osoitteessa http://api.example.net. Ilman CORSia selain estäisi tämän pyynnön SOP-käytännön vuoksi. CORSin avulla API-palvelin voi nimenomaisesti määrittää, mitkä alkuperät saavat käyttää sen resursseja, mikä mahdollistaa verkkosovelluksen oikean toiminnan.

Miten CORS toimii: Perusteet

CORS toimii asiakkaan (selaimen) ja palvelimen välillä vaihdettavien HTTP-otsakkeiden avulla. Palvelin käyttää näitä otsakkeita ilmoittaakseen selaimelle, onko sillä lupa käyttää pyydettyä resurssia. Keskeisin HTTP-otsake on Access-Control-Allow-Origin.

Skenaario 1: Yksinkertainen pyyntö

"Yksinkertainen pyyntö" on GET-, HEAD- tai POST-pyyntö, joka täyttää tietyt kriteerit (esim. Content-Type-otsakkeen arvo on application/x-www-form-urlencoded, multipart/form-data tai text/plain). Tässä tapauksessa selain lähettää pyynnön suoraan palvelimelle, ja palvelin vastaa Access-Control-Allow-Origin-otsakkeella.

Asiakaspyyntö (osoitteesta http://example.com):

GET /data HTTP/1.1
Host: api.example.net
Origin: http://example.com

Palvelimen vastaus (osoitteesta http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "data": "Tietoa palvelimelta"
}

Tässä esimerkissä palvelin vastaa otsakkeella Access-Control-Allow-Origin: http://example.com, mikä ilmaisee, että pyynnöt osoitteesta http://example.com ovat sallittuja. Jos pyynnön alkuperä ei vastaa Access-Control-Allow-Origin-otsakkeen arvoa (tai jos otsake puuttuu), selain estää vastauksen ja estää asiakaspuolen skriptiä pääsemästä käsiksi tietoihin.

Skenaario 2: Esikyselypyyntö (monimutkaisille pyynnöille)

Monimutkaisempien pyyntöjen, kuten PUT- tai DELETE-metodeja tai mukautettuja otsakkeita käyttävien pyyntöjen, kohdalla selain suorittaa "esikyselypyynnön" (preflight request) käyttämällä HTTP OPTIONS -metodia. Tämä esikyselypyyntö kysyy palvelimelta lupaa ennen varsinaisen pyynnön lähettämistä. Palvelin vastaa otsakkeilla, jotka määrittävät, mitkä metodit, otsakkeet ja alkuperät ovat sallittuja.

Asiakkaan esikyselypyyntö (osoitteesta http://example.com):

OPTIONS /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

Palvelimen vastaus (osoitteesta http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header, Content-Type
Access-Control-Max-Age: 3600

Otsakkeiden selitykset:

Jos palvelimen esikyselyvastaus osoittaa pyynnön olevan sallittu, selain jatkaa varsinaisen pyynnön lähettämiseen. Muussa tapauksessa selain estää pyynnön.

Asiakkaan varsinainen pyyntö (osoitteesta http://example.com):

PUT /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
X-Custom-Header: jokin-arvo
Content-Type: application/json

{
  "data": "Päivitettävää tietoa"
}

Palvelimen vastaus (osoitteesta http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "status": "Tiedot päivitetty onnistuneesti"
}

Yleiset CORS-otsakkeet

Tässä on erittely keskeisistä CORS-otsakkeista, jotka sinun tulee ymmärtää:

CORS eri palvelinpuolen kielissä

CORSin toteuttaminen tarkoittaa tyypillisesti palvelinpuolen sovelluksen määrittämistä lähettämään asianmukaiset CORS-otsakkeet. Tässä on esimerkkejä siitä, miten tämä tehdään eri kielissä ja kehyksissä:

Node.js ja Express

Voit käyttää cors-middleware-pakettia:

const express = require('express');
const cors = require('cors');

const app = express();

// Salli CORS kaikille alkuperille (KÄYTÄ VAROEN TUOTANNOSSA)
app.use(cors());

// Vaihtoehtoisesti määritä CORS tietyille alkuperille
// app.use(cors({
//   origin: 'http://example.com'
// }));

app.get('/data', (req, res) => {
  res.json({ message: 'Tämä on CORS-yhteensopiva kaikille alkuperille!' });
});

app.listen(3000, () => {
  console.log('Palvelin käynnissä portissa 3000');
});

Python ja Flask

Voit käyttää Flask-CORS-laajennusta:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Vaihtoehtoisesti määritä CORS tietyille alkuperille
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})

@app.route("/data")
def hello():
    return {"message": "Tämä on CORS-yhteensopiva kaikille alkuperille!"}

if __name__ == '__main__':
    app.run(debug=True)

Java ja Spring Boot

Voit määrittää CORSin Spring Boot -sovelluksessasi annotaatioiden tai konfiguraatioluokkien avulla:

Käyttämällä annotaatioita:

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin(origins = "http://example.com") // Salli pyynnöt osoitteesta http://example.com
public class DataController {

    @GetMapping("/data")
    public String getData() {
        return "Tämä on CORS-yhteensopiva osoitteelle http://example.com!";
    }
}

Käyttämällä konfiguraatiota:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/data")
                .allowedOrigins("http://example.com") // Salli pyynnöt osoitteesta http://example.com
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

PHP

 "Tämä on CORS-yhteensopiva osoitteelle http://example.com!");
echo json_encode($data);
?>

CORS ja turvallisuusnäkökohdat

Vaikka CORS mahdollistaa alkuperien väliset pyynnöt, on tärkeää toteuttaa se turvallisesti. Tässä on joitain tärkeitä näkökohtia:

CORS-ongelmien vianmääritys

CORS-ongelmien virheenkorjaus voi olla turhauttavaa. Tässä on joitain yleisiä ongelmia ja niiden ratkaisuja:

Vianmääritystyökalut:

Edistyneet CORS-skenaariot

Vaikka CORSin peruskäsitteet ovat suhteellisen yksinkertaisia, on olemassa joitain edistyneempiä skenaarioita, jotka on otettava huomioon:

CORSin parhaat käytännöt

Varmistaaksesi turvallisen ja tehokkaan CORS-toteutuksen, noudata näitä parhaita käytäntöjä:

Johtopäätös

CORS on kriittinen turvallisuusmekanismi, joka mahdollistaa hallitut alkuperien väliset pyynnöt verkkosovelluksissa. CORSin toiminnan ja sen oikean määrittämisen ymmärtäminen on välttämätöntä jokaiselle web-kehittäjälle. Noudattamalla tässä kattavassa oppaassa esitettyjä ohjeita ja parhaita käytäntöjä voit rakentaa turvallisia ja toimivia verkkosovelluksia, jotka ovat saumattomasti vuorovaikutuksessa eri alkuperistä peräisin olevien resurssien kanssa.

Muista aina asettaa turvallisuus etusijalle ja välttää liian sallivien CORS-määritysten käyttöä. Harkitsemalla huolellisesti CORS-asetustesi turvallisuusvaikutuksia voit suojata sovelluksesi ja tietosi luvattomalta käytöltä.

Toivomme, että tämä opas on auttanut sinua avaamaan CORSin mysteereitä. Hyvää koodausta!