Czym jest CORS?
CORS (Cross-Origin Resource Sharing) to mechanizm, który umożliwia bezpieczne udostępnianie zasobów między stronami internetowymi pochodzącymi z różnych domen.
Należy pamiętać że 192.168.0.1/ oraz 192.168.0.1/endpoint to dwie różne domeny i po próbie wysłania czegoś z klienta(przeglądarki) na endpoint serwera(esp-ka) napotkacie się na błąd CORS.
W nomenklaturze frameworku Arduino problem ten można rozwiązać po prostu wywołując na instancji serwera metodę server.enableCORS(true), przed jego uruchomieniem(co wygooglujecie w minutę). Zauważycie wtedy że lecą jakieś dziwne requesty HTTP_OPTIONS, serwer odpowie jakimiś dziwnymi nagłówkami ale to zignorujecie bo wszystko będzie działać. I dobrze.
W esp-idf musicie te wszystkie rzeczy obsłużyć sami. Przed próbą wysłania HTTP_POST na serwer, przeglądarka wyśle na Wasz endpoint 192.168.0.1/endpoint zapytanie HTTP_OPTIONS na które musicie odpowiedzieć. Wystarczy umieścić w odpowiedzi 3 headery. Przykładowy handler obsługujący corsa.
static esp_err_t cors_handler(httpd_req_t *req)
{
ESP_LOGI(TAG,"OPTIONS cors handler");
httpd_resp_set_hdr(req,"Access-Control-Allow-Headers","*");
httpd_resp_set_hdr(req,"Access-Control-Allow-Origin","*");
httpd_resp_set_hdr(req,"Access-Control-Allow-Methods","*");
httpd_resp_send(req,"",HTTPD_RESP_USE_STRLEN);
return ESP_OK;
}
<br />Dopiero po tej odpowiedzi przyjdzie właściwe zapytanie typu POST z danymi, które chcecie obsłużyć. Jak pod wpisem będzie 5 piorunów do napisze minimalistyczną apke(przykład) która będzie hostowała jakąś stronkę zbierającą dane i wysyłającą je do esp-ka
#programowanie #elektronika #raspberrypi
Zadziwiające
"Należy pamiętać że 192.168.0.1/ oraz 192.168.0.1/endpoint to dwie różne domeny"
że niby od kiedy?? To ta sama domena z inną ścieżką
@RolnikSamWdolinie jeśli mamy się czepiać słówek to tutaj w ogóle nie ma domeny. Tylko andres IP, domyślny port 80 i endpoint. 192.168.0.1:80 to origin. Jednak żeby uniknąć błędu CORS nie tylko origin musi się zgadzać ale również endpoint, co może być mylące bo CO z CORS to cross origin
@Gitler ale przecież przeglądarka nie zgłosi w tym przypadku błędu CORS, musi się różnić domena (adres IP) albo chociaż port. Query string może być dowolny. Aż to dzisiaj sprawdzę.
@PanPaweuDrugi owszem. Firefox i google chrome zgłaszają cors
@Gitler a na jakiej podstawie przeglądarka blokuje zapytanie pochodzące z tego samego origina? Bo query string nie jest częścią origina.
A nie wystarczy 5 piorunów nad wpisem? ( ͡° ͜ʖ ͡°)
Szanuję za podejście niskopoziomowe, kiedyś szukałem jakiegoś tutoriala do ESP8266, który by pokazywał jak to oprogramować po prostu w C, to wszędzie wyszukiwało tylko to jebane arduino albo inne node JS
@cec wystarczy. Co prawda ja pisze w C++ ale w tej apce nie musi być żadnych elementów C++
@Gitler Dobrze że to robisz, bo dokumentacja do wielu płytek to jest pieprzone dno i metr mułu, gdzie tak naprawdę 90% informacji to kolejne iteracje blink'a albo "to zadziała tylko przy wykorzystaniu konkretnego podzespołu a w przeciwnym wypadku wybuchnie Ci w twarz"
@Gitler brak przykładów? uzywales chatgpt?
@Klopsztanga w tym przypadku nie. Ale słabo sobie radzie w embeded. Każ mu napisać np. captive portal to się przekonasz
@Gitler mało bezpiecznie jest udostępniać * origin. Nagłówek Access-Control-Allow-Origin powinien wskazywać wyłącznie na twoją zaufaną domenę (w tym przypadku IP).
@Meverth zgadza się. Jednak cała komunikacji jest w sieci prywatnej dlatego pozwoliłem sobie na taką nonszalancje
@Gitler Jesteś pewien, że tu Cię CORS zablokował między jednym podkatalogiem w http://192.168.0.1 a drugim też http://192.168.0.1, a nie rozjechało się coś innego? To wg specyfikacji powinno matchować po całym ORIGINie (czyli protokół + adres/domena + port), a to z tego co piszesz był identyczne. Query string czy parametry getowe nie mają znaczenia dla CORSa.
Identyczny setup jak to co opisałeś mam w swoich projektach, i działa bez corsa. CORS generalnie jest po to, jeśli udostępniasz jakieś API na zewnętrzne serwisy, na jednym esp32 to totalny overkill.
Może tak for fun ustaw sobie w hostsach 192.168.0.1 na domenę exp32.lan i zobaczyć co się stanie jak tak otworzysz. Może masz zaszyty jakiś link bezwzględny ze złym adresem?
Reasumując - jeśli strona, z której idzie request na http://192.168.0.1/ to cokolwiek innego niż http://192.168.0.1/, to CORS jest potrzebny, jeśli są identyczne, to CORS nie powinien być wymagany.
@LondoMollari Masz racje. Niedopatrzenie w mojej strony. W przypadku który opisujesz nie będzie błędu cors. Jednak kiedy hostujemy stronke na serwerze esp i wysyłamy coś do niej z klienta w tej samej sieci to adresy IP są inne, stad błąd cors. Dodam sprostowanie
@Gitler Nie jestem pewien czy dobrze rozumiem, dlatego dopytam, ilustrując przykładem:
-
klient: to zawsze będzie przeglądarka, którą otwierasz swoją aplikację webową, powiedzmy z IP 192.168.0.100, ale to tutaj kompletnie nie ma znaczenia
-
serwer 1 (np. na jakimś PCcie czy RaspberryPI): 192.168.0.10 - tutaj stoi właściwa aplikacja webowa, javascripty, statyczne pliki, style css, etc, etc.
-
serwer 2 (na esp32): 192.168.0.20 - tutaj jest Twój webservice napisany w esp-idf
Jeśli teraz jest tak, że klient wchodzi na adres 192.168.0.10 a następnie javascripty wysyłają requesty XHR do esp32 pod adresem 192.168.0.20, to TAK - CORS będzie niezbędny, żeby JS mógł tak bezpośrednio odpytywać.
Jeśli klient wchodzi tylko i wyłącznie na adres 192.168.0.20, serwer pod 192.168.0.10 w ogóle nie istnieje, a wszystkie JSy i wszystkie elementy portalu są pobierane ze 192.168.0.20, to NIE, CORS nie powinien być potrzebny. Jeśli CORS jest wtedy wymagany, to coś jest tutaj prawdopodobnie popsute.
@Gitler tylko Twoi czytelnicy tego nie wiedzą. Będą bezmyślnie kopiować, doprowadzając do dziur bezpieczeństwa. Nie każdy się przejmuje bezpieczeństwem, nie każdy rozumie. W ogóle im bezpieczniej, tym trudniej a juniorom się nie chce, jak kiedyś...
Można tagować #embedded
@Gitler Nie zgodziłbym się że server http na esp to pospolity use-case. Pospolitym use-casem jest to że esp jest klientem i przesyła dane na serwer, albo że esp jest serwerem i komunikuje się z klientem za pomocą socketów TCP/UDP. Serwer http to jakiś overkill na zasadzie prześlemy obrazek z kamerki, ale i tak nie podłączy się pod to więcej niż jedna osoba w tym samym momencie.
@Gitler dawaj wincy tego mięsa o esp32
Zaloguj się aby komentować