Wesprzyj nas i przeglądaj Hejto bez reklam

Zostań Patronem
Robiem co mogę aby ułatwiać ludziom wejście do świata espidf ale czasami ręce mi opadają. Niektóre rzeczy, takie jak zmiana IP, serwery DNS można zrobić za pomocą jednej linijki w #arduino IDE, za to w esp-idf wymaga to wielkiego zachodu. W dodatku na Internecie brak jest przykładów, a dokumentacja jest niewystarczająco czytelna. Podzielę się z wami jak obsłużyć CORS - czyli to z czym będziecie musieli się zmagać, jak zaczniecie używać swojego #esp32 jako serwera http, czyli jakby się wydawało bardzo pospolity use-case. Aż dziwne że nie ma do tego przykładów.
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
23991c85-70cd-4ada-8c47-7064673c0e33
20

Komentarze (20)

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ś...

@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ć