Laden...

ASP.NET Core Razor Page - Formular verhindern von mehrfachen Submit (serverseitig)

Erstellt von Unfug vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.989 Views
U
Unfug Themenstarter:in
133 Beiträge seit 2006
vor 4 Jahren
ASP.NET Core Razor Page - Formular verhindern von mehrfachen Submit (serverseitig)

Hallo zusammen,

ich habe schon die Suche genutzt, habe aber nichts passendes gefunden. Wahrscheinlich ist es zu einfach und ich sehe den Wald vor lauter Bäumen nicht.

Genutzt wird ASP.NET Core Razor Pages

Es geht darum, dass ich ein Formular auf einer Webseite haben, dass einige Daten als POST übergibt.
In dieser Methode wird ganz viel berechnet auf Basis der Eingaben. Die Post Methode selbst braucht fast 5-10 Sekunden um alles durchgerechnet zu bekommen. Wenn alles passt, wird gespeichert, ansonsten muss der Benutzer seine Eingaben korrigieren.

Das Problem ist, sobald der Submit Button im Formular gedrückt wird, kann ein Benutzer mehrfach auf Submit drücken. Simulieren kann man das, indem man z.B. einfach ein Task.Delay(10000) in die POST Methode einbaut.

Clientseitig kann ich den Submit Button "deaktivieren" per Javascript, jedoch gibt es für diese spezielle Seite Benutzergruppen, die Javascript nicht erlauben und auch per Internet Explorer surfen.
Ich muss aber auch serverseitig unterbinden, dass z.B. jemand über Tools versucht mehrfach Submits durchzuführen.

Meine Frage: Wie kann ich das machen bzw. habt ihr Erfahrung damit?

Schöne Grüße und Danke

16.806 Beiträge seit 2008
vor 4 Jahren

Wie du schon gemerkt hast wird der Button und damit der Submit Clientseitig ausgeführt.
Von Serverseite kannst Du hier nichts unterbinden.

Du kannst Dir aber eine eigene Routine schreiben, die den Submit prüft.
Fertig gibt es hier nichts - wie auch 😃

U
Unfug Themenstarter:in
133 Beiträge seit 2006
vor 4 Jahren

Danke,

also ich müsste dann irgendwie, z.B. durch Hidden Values, es hinbekommen, dass ich das Formular + Submit eindeutig identifzieren kann und einen Status setze
z.b. "abgesendet, fehler, abgeschlossen"

Also dies dann z.B. in einer Datenbank zwischenspeichern.

Soetwas?

T
2.219 Beiträge seit 2008
vor 4 Jahren

Du könntest die Information auch im Cache oder in der Session speichern.
Dafür extra einen DB Eintrag zu machen, wenn du eh nur doppelte Requests abfangen willst, wäre doch etwas viel des guten?

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

U
Unfug Themenstarter:in
133 Beiträge seit 2006
vor 4 Jahren

Danke. Ja klingt gut.
Ich probier es mal aus

16.806 Beiträge seit 2008
vor 4 Jahren

Auf keinen Fall den Cache dafür missbrauchen! Absolutes No-Go!
Die Session könnte man dafür nehmen, aber viele Einträge in einer Session und viele Benutzer führt schnell zum Memory-Limit einer Webanwendungen.

U
Unfug Themenstarter:in
133 Beiträge seit 2006
vor 4 Jahren

Auf keinen Fall den Cache dafür missbrauchen! Absolutes No-Go!
Die Session könnte man dafür nehmen, aber viele Einträge in einer Session und viele Benutzer führt schnell zum Memory-Limit einer Webanwendungen.

Gibt es dazu eine einfache Erklärung warum?
Bei MS steht zwar auch, dass Apps nicht vom Cache abhängen sollten/dürfen, aber vielleicht hast Du ja eine weitere Aussage.
https://docs.microsoft.com/de-de/aspnet/core/performance/caching/memory?view=aspnetcore-2.2

16.806 Beiträge seit 2008
vor 4 Jahren

HTTP Basics: du weißt niemals wann es einen neuen Request gibt.
Daher sollst Du niemals solche spezifischen Informationen in den kostbaren RAM legen, wenn du niemals sicher gehen kannst, dass du die Informationen je irgendwann nochmal brauchst.

In den Cache gehören nur wirklich spezifische Daten, die mehrfach benötigt werden, um andere Ressourcen (zB Datenbank) zu entlasten.

U
Unfug Themenstarter:in
133 Beiträge seit 2006
vor 4 Jahren

Danke

Hinweis von Abt vor 4 Jahren

Bitte keine Full Quotes
[Hinweis] Wie poste ich richtig?

T
2.219 Beiträge seit 2008
vor 4 Jahren

@Abt
Was den RAM angeheht, würde ich dir nur bei Embedded und Low-End Hardware zustimmen.
Bei allen anderen Systemen würde ich dir wiedersprechen.

Gerade im Server Bereich sind wird schon bei Systemen jenseits der 1TB RAM angekommen.
Die Zeiten von kostbaren RAM sind selbst bei Desktop Systemen seit 10-15 Jahren vorbei.
Wenn man nicht gerade im reinen Embedded Bereich arbeitet, ist RAM in Hülle und Fülle vorhanden.
Nur steht davon auch nichts im ganzen Thread.

Ansonsten würde ich die Speicherung in der DB nur als Lösung in Betracht ziehen, wenn mit den Informationen mehr passieren soll.
Ich würde keine Daten in der DB parken, die eh nach erfolgtem Durchrechnen verworfen werden würden.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.806 Beiträge seit 2008
vor 4 Jahren

Tut mir leid T-Virus, aber mit der Argumentation stehst Du leider relativ weit im Abseits.

Webanwendungen und deren Technologien haben den absoluten Fokus der Ressourceneffizienz, damit sie skalierbar sind.
Natürlich magst Du vielleicht ein Server mit TB am RAM haben - sinnvoll ist was anderes.
Skalierung funktioniert im Web vor allem horizontal (scale out) und nicht vertikal (scale up).

Wenn Du meinst, dass Du alles in den RAM ballern willst; mach das.
Aber bitte empfehl das keinem weiter - das ist nicht Sinn der Sache und wird bei allen Webtechnolgien allein vom Grundlagenkonzept abgeraten.

T
2.219 Beiträge seit 2008
vor 4 Jahren

Wie sehe den die Lösung über die DB aus bzw. was wäre deiner Meinung nach der Vorteil davon überhaupt solche kurzlebigen Informationen in der DB abzuspeichern?
Ich sehe hier keinen sinnvollen Nutzen, wenn man die Daten nicht späer für Reporting o.ä. auswerten will oder diese andersweitig verwendet.

Da hier auch geskrippte Massen Anfragen als Szenario mit eingeplant werden müssen, was der TE auch selbst schreibt, würdest du also Massenabfragen gegen die DB laufen lassen?
Gehen wir mal davon aus, dass ich per Skript locker 100.000 Anfragen pro Sekunde laufen lassen kann.
Wenn der Webserver unter der Last nicht zusammen bricht, kann ich also entweder deine gesammten DB Verbindungen aufbrauchen, was zu vielen Fehlern an anderer Stelle in der Anwendung führt oder deine DB durch die Abfragen sogar überlasten.

Also müsste man im nächsten Schritt um diese beiden Angrifffsvektoren abzufangen, wieder auf den Cache oder die Session gehen.
Im Endeffekt also einen SChritt vor um wieder einen Schritt zurück zumachen.

Ich weiß zwar nicht in welchem Bereich du beruflich tätig bist, aber solche Szenarien scheinen bei dir scheinbar nicht vorzukommen und somit auch nicht auf deinem Schirm zu sein.
Ich habe damit schon öfters Erfahrungen gemacht und habe auch entsprechende Maßnahmen getroffen um solche Probleme abzufangen.

Ich sehe hier einfach keine Vorteile solche Daten in der DB zu lagern, wenn diese spätestens nach dem durchrechnen wieder verworfen werden.
Gerade wenn es dann zu DB Problemen kommt, z.B. die Verbindung kann beim löschen nicht mehr aufgebaut werden, steht in der DB auch ein Eintrag in Arbeit.
Dieser müsste dann entweder auch nach Zeitraum X oder manuell durch einen DBA gelöscht werden.
Und dieser Fall kommt leider öfters vor als man denkt.

Was meinen vorherigen Kommentar angeht, scheinst du die Kernaussage nicht verstanden zu haben.
Es geht mir nicht darum alles in den RAM zu packen, macht auch keinen Sinn wenn es keine Notwendigkeit dafür gibt.
Umgekehrt gilt das gleiche aber auch für die Datenbank.
Nur weil man Daten dort parken kann, sollte man es nicht wenn es keine Notwendigkeit dafür gibt.

Es geht mir auch nicht um Skalierung sondern vielmehr um die reine Datenhaltung.
Und hier scheinst du dich auch sehr wild zu verrechnen.
Wir reden hier von ein paar Bytes pro Benutzer.
Selbst wenn 10.000 Benutzer hier einen Cache Eintrag bekommen würde, reden wir von ein paar Kilobyte an Daten die im RAM liegen müssten.
Wenn man diese Anpassung nicht gerade bei Facebook macht, dann reden wir vermutlich von einem unbedeutenem RAM Verbrauch der auf durch entsprechende Cache Lebenszeiten nur von begrenzter Dauer wäre.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
461 Beiträge seit 2013
vor 4 Jahren

Ich z.Bsp. arbeite demnächst am Load-Balancing, da sind Daten im RAM nur sehr begrenzt zu empfehlen, sonst würde das ganze System nicht richtig funktionieren ohne das die Server voneinander wissen müssen und das sollte es natürlich nicht sein.

Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄

16.806 Beiträge seit 2008
vor 4 Jahren

Wie sehe den die Lösung über die DB aus bzw. was wäre deiner Meinung nach der Vorteil davon überhaupt solche kurzlebigen Informationen in der DB abzuspeichern?

Die Frage ist alleine schon, warum Du überhaupt Daten dazu abspeichern musst - denn das kannst Du nicht pauschal sagen.
Wir im Forum prüfen hier auch, dass niemand zu schnell Themen eröffnet - das ist aber reine Logik.
Die Logik prüft hier nur, in welchem Zeitabstand zu versuchst Themen zu erstellen; dazu brauch ich gar nicht irgendwo Daten zusätzlich speichern.

Da hier auch geskrippte Massen Anfragen als Szenario mit eingeplant werden müssen, was der TE auch selbst schreibt, würdest du also Massenabfragen gegen die DB laufen lassen?

Wir kennen die Kriterien gar nicht. Daher empfehle ich hier auch nichts.
Du scheinst aber deutlich mehr zu Wissen als der Threadersteller von sich gibt 🙂

Also müsste man im nächsten Schritt um diese beiden Angrifffsvektoren abzufangen, wieder auf den Cache oder die Session gehen.

a) der Cache hat einen völlig anderen Zweck, den Du hier missbrauchst
b) eine Session kann bei einer skalierenden Anwendung nicht im RAM liegen, sondern muss auf einen Redis oder eine DB ausgelagert werden. Ansonsten brauchst Du Sticky Sessions, die keiner will.
Empfohlen wird: vermeide Sticky Sessions, wenn möglich.

Hier ist es möglich.

Ich weiß zwar nicht in welchem Bereich du beruflich tätig bist, aber solche Szenarien scheinen bei dir scheinbar nicht vorzukommen und somit auch nicht auf deinem Schirm zu sein.

Ich bin Unternehmensberater, maßgeblich als Lead Architect für hybride bzw. Cloud-basierte Plattformen im Bereich Maschinenbau und IoT (kann auch jeder im Profil lesen oder ergooglen; bin einfach zu finden).
Behaupte durchaus, dass ich weiß, wie man Webanwendungen, Services und Plattformen skaliert: und zwar nicht vertikal.

Dein Beitrag, voll von Unterstellungen, ist leider mal wieder nicht zielführend und Deine Argumentation ist völlig an den aktuellen Webtechnologien vorbei.
Bleib doch einfach sachlich mit Fakten 🙂

Alle Technologien im Web, sei es .NET, NodeJS, Java.. haben konzepte, die horizontal skalieren; nicht vertikal.
Da kannst Du auch rechnen wie Du willst: horizontale Skalierung ist einfach günstiger, hat eine höhere Verfügbarkeit und eine höhere Leistungsfähigkeit.

Und da alle Konzepte eben auf die vertikale Skalierbarkeit aus sind ist es ein absoluter Quark jemanden eine Lösung zu empfehlen, die vertikal orientiert ist.
Das ist nicht der Sinn des Webs, geht an allem Empfehlungen und an allen Konzepten vorbei.

sonst würde das ganze System nicht richtig funktionieren ohne das die Server voneinander wissen müssen und das sollte es natürlich nicht sein.

Eben 🙂 👍

T
2.219 Beiträge seit 2008
vor 4 Jahren

Ich weiß ehrlich gesagt nicht, warum du immer wieder aus Kommentaren Unterstellungen raus lesen kannst oder dich scheinbar angegriffen fühlst, wenn ich nicht deiner Meinung bin.
Muss ein spezielles Talent von dir sein oder ein Ego Problem, kannst du dir aussuchen.

Ansonsten spielen auch deine Aussagen zur Skalierung überhaupt keine Rolle, war nicht mal von mir in irgend einer weise angesprochen worden.
Die Skalierung ist hier nicht das Ziel/Thema, sondern die Datenhaltung.
Aber wenn ich dir dies sogar zweimal sagen muss und die ignorierst es, scheint das Thema nicht mehr fortführbar zu sein.

Ich muss aber auch serverseitig unterbinden, dass z.B. jemand über Tools versucht mehrfach Submits durchzuführen.

Scheinbar hast du auch den ersten Beitrag des TE nicht komplett gelesen.
Aber bei dem Satz sehe ich sehr wohl auch Skripte oder Tools die Massenabfragen generieren können.

Alles weitere können wir gerne per PN klären, da wir schon längst Off-Topic sind.
Von meiner Seite aus ist auch alles gesagt hier muss der TE entscheiden wie er es umsetzt.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.806 Beiträge seit 2008
vor 4 Jahren

Die erneuten persönlichen Kommentare ohne inhaltlichen Zusammenhang lasse ich unbeantwortet.

Ansonsten spielen auch deine Aussagen zur Skalierung überhaupt keine Rolle, war nicht mal von mir in irgend einer weise angesprochen worden.
Die Skalierung ist hier nicht das Ziel/Thema, sondern die Datenhaltung.

Doch. Daten im RAM skalieren nicht. Technisch nicht möglich.
Ein Cache hat wie gesagt einen anderen Zweck und eine Session skaliert nur, wenn diese ausgelagert wird zB. in Redis oder in eine DB.

Und nochmal: alleine der Hinweis steht im Gegensatz zu den allgemeinen Konzepten und der allgemeinen, dokumentierten Empfehlung der jeweiligen Technologien.

Ich muss aber auch serverseitig unterbinden, dass z.B. jemand über Tools versucht mehrfach Submits durchzuführen.
Scheinbar hast du auch den ersten Beitrag des TE nicht komplett gelesen.
Aber bei dem Satz sehe ich sehr wohl auch Skripte oder Tools die Massenabfragen generieren können.

.. was die Serverseitige Validierung begründen soll, dass eben JavaScript auf Client-seitig nicht ausreicht. Korrekt.
Und für eine Serverseitige Implementierung ist es völlig egal, ob der Request per Client-App oder über irgendwelche Script kommt.
Daher ist der Hinweis ohnehin redudant 😉