ja, hast Recht. Evtl. stufe ich das zu wichtig ein und man kann darauf verzichten.
iframes sollten ja auch in künftigen Browser-Versionen kein Problem darstellen, oder was meinst du?
Aber hast du noch einen Tipp (sorry, das ich dich grad so beanspruche wir man die übermittelten Daten am smartesten im SPIFFS speichert um diese später wieder auslesen zu können?
Mit dem was ich aktuell mache, also mit dem * als Trennzeichen, bin ich nicht wirklich sicher unterwegs. Aber warte: während ich diese Zeilen schreibe kommt mir glaube ich selber eine Lösung: wäre ein struct der beste Weg? Und diesen dann in eine (binäre) Datei schreiben?
naja du machst jetzt einen Screenshot von einer Seite die sich mit CORS und SOP beschäftigt.
Nichts davon ist unmittelbar relevant für deinen Usecase.
Ich sag nicht das iframes schön sind, aber sie sind meines Wissens in HTML5 nicht abgekündigt.
Es dient lediglich als target.
SPIFFS ist auf einigen ESPs deprecated. Ich weis aber nicht auf welchem du bist.
Zum persistieren von Daten würde ich am ESP32 (???) preferences nehmen und die Daten in einem struct halten.
am ESP8266 halt in der EEPROM emulation - aber wieder in einem struct.
Ein über einen Browser gesendetes JSON würde ich nicht 1:1 ungeprüft in in ein File übernehmen oder verarbeiten wollen.
Ich will dich nicht als Google verwenden, aber lauf ich mit ESP32 und SPIFFS nicht zukunftssicher? Ist die Alternative dazu dann LittleFS?
Was meinst du mit "preferences" nehmen? Im Struct halten kapier ich
Inwiefern prüfen? Welche Gefahr lauert? Sorry, ich hoffe die Frage ist nicht allzu dumm.
Aber wenn ich im HTML5 Formular die Form-Daten validiere (bzw. per Javascript) und dann per JSON sende, sollte doch hinten schon auch alles unbeschädigt ankommen, oder?
Du machst mir Angst
Dass man nach Analyse Deines Formulars problemlos beliebige Daten senden kann und Du das nicht verhindern kannst.
Beliebtes Beispiel: SQL-Injection (bei Dir wohl nicht zutreffend). Bei falschen Rechten mal ins Passwortfeld eingeben: aaa; Drop Database;
Da hast Recht, SQL-Injection spielt im Web-Bereich definitiv ne Rolle.
Aber das Problem hab ich doch auch mit einem reinen HTML Formular (POST method) ohne ajax.
Das ist ja ein grundsätzliches Problem, oder?
Gut zu wissen, Danke.
Und da auch mit Core 1 LittleFS schon unterstützt wird, wäre es definitiv gut, gleich umzusteigen.
Ich hoff mal, die Unterschiede zwischen LittleFS und SPIFFS sind nicht allzu groß (von der Syntax). Hab mich bisher nur mit SPIFFS beschäftigt.
Und da die vorangeganene Diskussion ja darum ging, welche Übertragungsmethode am besten wäre, hab ich in seinem Kommentar schon das Wort JSON als hervorgehoben gesehen.
Aber ist ja völlig egal: ein HTML-Formular bietet immer Angriffspotential und sollte (wo erforderlich) natürlich auch entsprechend geprüft werden.
ich weis nicht in welchem deiner x Threads das war, aber wenn das von mir war dann habe ich deine Fragestellung nach der Übertragung um "Daten vom Server an den Client senden" aufgefasst. Das würde ich durchaus mit JSON machen.
Aber für ein paar Daten vom Client zum Server schicken, würde ich Parameter nehmen.
OK Danke dir @noiasca .
Wieder mal viel input. Auch die Preferences sind mir bisher unbekannt gewesen.
Muss ich mich dringend mit beschäftigen.
Bis zum heutigen Tage habe ich z.B. ssid, passwort und andere Einstelldaten in einer txt im SPIFFS abgelegt und diese SPIFFS beim Starten des ESP ausgelesen. Wieder was dazu gelernt.
ich hab jetzt mal versucht, alles umzusetzen, was mir hier genannt wurde.
Ich sende die Daten nun mit einem "purem" HTML POST
Ich speichere die Daten im eeprom (preferences)
Ich lade die Seite direkt nach dem Senden der Formulardaten einfach neu. So bleib ich auf der Seite und brauche auch keinen iframe. Warum ich da niocht gleich drauf gekommen bin...?
Ich verschlüssle die Daten vor dem Speichern auch gleich noch
Hier mein fertiger Testsketch:
#include <WiFi.h>
#include <WiFiAP.h>
#include <WebServer.h>
WebServer server(80);
#include <Preferences.h>
Preferences prefs;
// Zum Verschlüsseln...
#include "mbedtls/aes.h"
#include "Cipher.h"
char key[17] = "weogrbasztvszvas";
const char datei_wlan[12] = "/wlan.txt";
char APssid[25] = "MyAccesspoint";
char APpassword[20] = "123456789";
char ssid[30]="";
char password[30]="";
const char indexPage[] PROGMEM = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
</head>
<body>
<form action="/setData" method="POST" onsubmit="return setData()">
<p>SSID:</p>
<input type="text" name="ssid" id="ssid" value="">
<p>Passwort:</p>
<input type="password" name="password" id="password" value="">
<button type="submit">Submit</button>
</form>
</body>
<script>
function setData() {
// Daten ggf. noch prüfen...hier mal nur zum Test was dranhängen
var ssid=document.getElementById("ssid").value;
var password=document.getElementById("password").value;
document.getElementById("ssid").value=ssid + " XYZ";
// Und dann das Formular senden
return true;
}
</script>
</html>
)=====";
void setup(){
Serial.begin(115200);
// Verschlüsselung initiieren
Cipher * cipher = new Cipher();
cipher->setKey(key);
// Kurze Pause nur zu Testzwecken (Serielle Ausgabe soll lesbar sein)
delay(2000);
// Zugangsdaten laden
prefs.begin("zugangsdaten", false);
// Preferences auslesen und decoden
String ssid_encoded = cipher->decryptString(prefs.getString("ssid", ""));
String password_encoded = cipher->decryptString(prefs.getString("password", ""));
// Entschlüsselten Daten in char-arrays schreiben
ssid_encoded.toCharArray(ssid, sizeof(ssid));
password_encoded.toCharArray(password, sizeof(password));
prefs.end();
Serial.println("SSID entschlüsselt beim Starten: " + (String)ssid + " Passwort entschlüsselt beim Starten:" + (String)password);
server.on("/", display_root);
server.on("/setData", setData);
WiFi.mode(WIFI_AP);
WiFi.softAP(APssid, APpassword);
server.begin();
}
void loop(){
server.handleClient();
}
void display_root() {
const char * httpType PROGMEM = "text/html";
server.send_P(200, httpType, indexPage);
}
void setData() {
// Verschlüsselung initiieren
Cipher * cipher = new Cipher();
cipher->setKey(key);
prefs.begin("zugangsdaten", false);
if (server.method() != HTTP_POST) {
Serial.println("Fehler! Formular konnte nicht gesendet werden.");
server.send(200, "text/plain", "Fehler");
} else {
for (uint8_t i = 0; i < server.args(); i++) {
if (server.argName(i)=="ssid") {
prefs.putString("ssid", cipher->encryptString(server.arg(i)));
Serial.println("Kodierte SSID:" + prefs.getString("ssid", ""));
server.arg(i).toCharArray(ssid, sizeof(ssid));
} else if (server.argName(i)=="password") {
prefs.putString("password", cipher->encryptString(server.arg(i)));
Serial.println("Kodiertes Passwort:" + prefs.getString("password", ""));
server.arg(i).toCharArray(password, sizeof(password));
}
}
prefs.end();
Serial.println("SSID nach dem Speichern: " + (String)ssid + " Passwort nach dem Speichern:" + (String)password);
// Seite neu laden...
const char * httpType PROGMEM = "text/html";
server.send_P(200, httpType, indexPage);
}
}
Über Anmerkungen / Verbesserungsvorschläge freue ich mich
Dazu gleich noch ne Frage:
Wieviel Platz ist denn inden Preferences? Wenn ich da ca. 30 key/value Paare speicher, sollte das doch kein Problem sein, gelle?
In dem Test hab ich die Überprüfung der Daten weggelassen (daher der Kommentar).
Sollte nur ein Beispiel sein, an welcher Stelle man vor dem Senden des Formulars noch ran könnte. Einen Teil der Überprüfung werd ich sicherlich dann genau an dieser Stelle machen, einen Teil auch schon auf HTML5 Ebene (z.B. über die Typisierung von Feldern, min-max-Grenzen. Kommt eben drauf an, welchen Anwendungsfall man hat.
Schutz davor, dass ein böser Onkel die Daten auslesen könnte. Oder ist das übertrieben?
Keine Ahnung, kann man natürlich auch weglassen.
Edit:
Fips macht das zum Beispiel bei seinem Login-Manager auch
Ah ok. Da hatte ich mich falsch ausgedrückt sorry.
Aber mal so in den Raum gefragt: Wieviel Wertepaare sind denn in den Preferences möglich?
Laut meiner Info stehen 20KB zur Verfügung. Das dürfte doch für hunderte reichen, oder?