PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PHP: Umfragergebnis kann mit F5 erhöht werden


Onlinejunky
2008-02-03, 12:42:07
Hi Leute,

ich habe da ein kleines Problem. Unser Informatiker hat uns bei einem Projekt verlassen und eine kleine Baustelle hinterlassen.

Er hat eine Umfrage programmiert. Das Problem ist, dass man die Umfrage noch durch die Tast F5 manipulieren kann und es so immer eine Stimme hinzuzählt.

Was genau kann ich tun, um das zu unterbinden?


Gruß

Gast
2008-02-03, 13:00:19
Du könntest bspw. auf dem Rechner des Votenden nen Cookie hitnerlegen und sobald das da ist, kann er für 24h nicht mehr abstimmen.

Ist aber eher unsauber...

Besser ist es die IP zu speichern und 24h (je nach dem wie lang er nicht mehr können soll, größer 24h macht aber dank der DSL-Trennung nach ziemlich genau 24h nicht wirklich Sinn) zu sperren.

Onlinejunky
2008-02-03, 13:04:07
Aber die IP wechselt doch immer und ist dynamisch.

Kann ich die F5 Taste nicht irgendwie sperren?


Gruß

darph
2008-02-03, 13:19:17
Aber die IP wechselt doch immer und ist dynamisch. Cookies haben mit der IP nyx zu tun. Die haben was mit dem Browser zu tun.

Kann ich die F5 Taste nicht irgendwie sperren?Nein.


Das Problem scheint an unsauberem Session-Management zu liegen. (Wäre es eine POST-Variable, würde der Browser immer nachfragen: "Nochmal senden?". Wäre es eine GET-Variable gehört der Programmierer gevierteilt. X-D In beiden Fällen muß man dann per User speichern, ob er votiert hat. Siehe unten)

Vermutlich sieht das ungefähr so aus:

if (isset($_SESSION["blafasel"])) {
$ergebnis["blafasel"] += 1;
}

oder so.

Was vielleicht hilft: Ganz am Ende der Seite session_unset() (http://de3.php.net/manual/en/function.session-unset.php) aufrufen.

Aber dabei ist Vorsicht geboten: Wenn die User auch per Session eingeloggt sind, werden sie ausgeloggt.

Sicherer ist, wenn du herausfindest, welche Session-Variable(n) dafür genau verantwortlich sind. Die löschst du dann mit

unset($name) (http://de3.php.net/manual/en/function.unset.php). Aber:

Note: If $_SESSION (or $HTTP_SESSION_VARS for PHP 4.0.6 or less) is used, use unset() to unregister a session variable. Do not unset() $_SESSION itself as this will disable the special function of the $_SESSION superglobal.


Das löst das Problem, daß ein Nutzer durch ständiges neu Laden der Seite (Ob jetzt mit der Taste F5 oder mit Enter oder klicken auf den Reload-Button ist hier völlig egal) den Counter immer weiter hochzählen kann. Das löst nicht das Problem, daß ein User potentiell zwei Mal abstimmen kann. Je nachdem, wie und ob Eure User sich überhaupt authentifizieren, müßte man das in einem Cookie hinterlegen (unsicher aber meist ausreichend), oder aber in einer Datenbank speichern, wer votiert hat.

The_Invisible
2008-02-03, 13:29:56
Du könntest bspw. auf dem Rechner des Votenden nen Cookie hitnerlegen und sobald das da ist, kann er für 24h nicht mehr abstimmen.

Ist aber eher unsauber...

Besser ist es die IP zu speichern und 24h (je nach dem wie lang er nicht mehr können soll, größer 24h macht aber dank der DSL-Trennung nach ziemlich genau 24h nicht wirklich Sinn) zu sperren.

warum nicht beides kombinieren?

die wenigsten werden sich genau das cookie von tausenden suchen und löschen und dann auch noch neu einwählen. dazu noch die einschränkung das man ohne cookies nicht abstimmen kann und vielleicht noch ein intelligentes captcha gegen dumme bots und schon passt es.

mfg

darph
2008-02-03, 13:34:10
warum nicht beides kombinieren?
Weil oftmals ganze Netzwerke nur eine externe IP haben.

Onlinejunky
2008-02-03, 13:39:28
Hi,

soweit ich das gesehen habe, ist da gar nichts mit Sessions gesetzt.
Also es erfolgt keine Abfrage.

Kann man da nicht ne ganz einfach Lösung machen, auch wenn die vielleicht nicht prof. ist.

Also es wurde mit Post gemacht und der Browser fragt dann jedes mal, ob man neu senden will.

Gruß

Thomas(:
2008-02-03, 13:53:18
Besser ist es die IP zu speichern und 24h (je nach dem wie lang er nicht mehr können soll, größer 24h macht aber dank der DSL-Trennung nach ziemlich genau 24h nicht wirklich Sinn) zu sperren.

Man darf IP-Adressen nicht ohne Zustimmung des Nutzers speichern.

<?PHP

session_start();
if(isset($_SESSION['voteblock'])) die("ganz böser Junge");
$_SESSION['voteblock'] = 1;

//...

Nicht schön, aber das wolltest du ja auch nicht. (auch ungetestet...)

The_Invisible
2008-02-03, 14:37:20
Weil oftmals ganze Netzwerke nur eine externe IP haben.

naja, auf nat-behinderte user wird aber nur wenig rücksicht genommen, selbst von größeren firmen. ka ob das project wirklich so professionell sein muss

mfg

Onlinejunky
2008-02-03, 17:40:19
Man darf IP-Adressen nicht ohne Zustimmung des Nutzers speichern.

<?PHP

session_start();
if(isset($_SESSION['voteblock'])) die("ganz böser Junge");
$_SESSION['voteblock'] = 1;

//...

Nicht schön, aber das wolltest du ja auch nicht. (auch ungetestet...)

Sorry, dazu brauch ich noch ne Erklärung, wie das dann genau geht.

Also wenn ich das richtig verstanden habe, dann geht das mehrfach abstimmen nicht, wenn "voteblock" auf "1" steht.

Ich muss das ja irgendwie einleiten oder, dass wenn man auf Absenden drückt, dass voteblock auf 1 gesetzt wird und dann die Abfrage kommt. Irgenwie fehlt hier doch was oder. Also es sind 2 Seiten. Auf ersten Seite wird abgestimmt und auf Senden gedrückt. Auf der zweiten werden die Daten aus der Datenbank gezogen und da muss ich es irgendwie unterbinden, dass man refreshen kann.

Gruß

Edit: Wie lange steht dann voteblock auf "1", wann darf man wieder abstimmen.

Gast
2008-02-03, 17:44:46
Wenn die Session abläuft, also im Normalfall bis man den Browser schließt.

Onlinejunky
2008-02-04, 12:36:01
Man darf IP-Adressen nicht ohne Zustimmung des Nutzers speichern.

<?PHP

session_start();
if(isset($_SESSION['voteblock'])) die("ganz böser Junge");
$_SESSION['voteblock'] = 1;

//...

Nicht schön, aber das wolltest du ja auch nicht. (auch ungetestet...)

Hi,

ich habe das jetzt eingebaut und das funktioniert super.
Ohne große Abfragen mit IPs oder Cookies. Die Lösung gefällt mir.

Wenn man auf F5 drückt und die Post Daten wiederholt sendet, kommt die Meldung "Es darf nur einmal abgestimmt werden :-P"

Dann muss man extra den Browser im neue starten. Aber wer macht das.

Gruß

Onlinejunky
2008-02-04, 12:54:34
Hi,

ein Problem habe ich jetzt jedoch.

Wenn ich unter der Umfrage einen Link hinmache "Ergebnis anschauen" und ich verlinke auf die Ergebnis Seite, macht der gleich "die".

Wie kann ich das unterbinden?


Gruß

Kinman
2008-02-04, 12:59:14
Statt die() zeigst gleich das Ergebnis an ;)

mfg Kinman

Onlinejunky
2008-02-04, 13:25:21
Ja schon, aber dann ist die die() Funktion ja wieder weg, wenn man normal abstimmt. Verstehst du? Dann kann man wieder F5 drücken. Das ist ja die selbe Seite, die angesprochen wird, nur einmal eben direkt.

Kann ich dann vielleicht eine 3. PHP Datei aufmachen.

?><form name="umfrage" method="post" action="umfrage_der_woche2.php" onsubmit="return ueberpruefen();">

bei action noch eine umfrage_der_woche3.php dazu machen und bei dieser das die() entfernen?


gruß

Kinman
2008-02-04, 13:35:13
Nein, wenn man nochmals aktualisiert, wird das Ergebnis angezeigt. Eventuell musst Du noch ein exit(); dranhängen

mfg Kinman

Onlinejunky
2008-02-04, 13:46:03
Hm,

also es funktioniert aber und geniale ist. Jetzt kann man die aktuelle Umfrage anzeigen lassen und kann so viel F5 drücken wie man will. Es lädt nur die Seite neu.

Gruß

Onlinejunky
2008-02-04, 14:20:29
Hi,

jetzt stehe ich noch vor einem Problem.

session_start();
if(isset($_SESSION['voteblock'])) die("Es darf nur einmal abgestimmt werden");
$_SESSION['voteblock'] = 1;

Kann ich diesen String der unter die() steckt auch verlinken? Also wenn ich <h2> davor setzt wird die Schrift dick aber wie kann ich da ein href Befehl einfügen?

Gruß

Gast
2008-02-04, 14:28:04
Wieso die ganze Arbeit? Sowas kann man ganz einfach mit JavaScript lösen.
Mal im Netz nach JavaSript Webforms support suchen.. oder ähnliches.

Onlinejunky
2008-02-04, 14:32:06
Mit Javascript kenne ich mich gar net aus. Es ist auch nicht viel Arbeit denke ich mal aber ich muss doch diesen String unter "die" irgenwie bearbeite können oder?

Kinman
2008-02-04, 14:32:18
Hi,

jetzt stehe ich noch vor einem Problem.

session_start();
if(isset($_SESSION['voteblock'])) die("Es darf nur einmal abgestimmt werden");
$_SESSION['voteblock'] = 1;

Kann ich diesen String der unter die() steckt auch verlinken? Also wenn ich <h2> davor setzt wird die Schrift dick aber wie kann ich da ein href Befehl einfügen?

Gruß


die("<a href=\"http://3dcenter.de\">3D-Center</a>");


oder


die('<a href="http://3dcenter.de">3D-Center</a>');

mfg Kinman

Onlinejunky
2008-02-04, 14:54:50
Hi,

vielen Dank. Ich wusste doch, dass ich Fehler bei den "" gemacht habe.

Gruß

Edit: Ich könnte doch theoretisch jetzt auch ein include Befehle da rein machen oder?

Also das hier geht leider nicht: die('include ("../index.php")');

Gast
2008-02-04, 15:04:21
Mit Javascript kenne ich mich gar net aus. Es ist auch nicht viel Arbeit denke ich mal aber ich muss doch diesen String unter "die" irgenwie bearbeite können oder?


Ne ich meinte, mit JavaScript kann man perfekt Webforms steuern bevor ein POST entsteht. Also man kann sehr schön überprüfen ob Leute alles ausgefüllt haben usw...

Kinman hat es dir ja schon gezeigt..

So mal als Erinnerung... Wenn du etwas als String ausgibst und selber im String " nutzen willst.. musst du das immer durch ein \ trennen. Also so wie du es dort sehen kannst \".

Onlinejunky
2008-02-04, 15:16:39
Also irgendwas mache ich noch falsche mit den "".

die('header ("Location: http://www.computerhilfen.de")');


ist das überhaupt möglich?


Gruß

Edit: Also ich habe es jetzt so gemacht die('<meta http-equiv="refresh" content="0; URL=http://www.computerhilfen.de">');

Wahrscheinlich kann ich nicht php in php machen oder? Mich würde das aber trotzdem interssieren.

creave
2008-02-04, 15:42:57
Nein, wenn man nochmals aktualisiert, wird das Ergebnis angezeigt. Eventuell musst Du noch ein exit(); dranhängen

mfg Kinman


Laut dem PHP-Manual entspricht exit() -> die(), ist also das selbe. Oder wie meintest du das mit dem zusätzlichen exit?


Also irgendwas mache ich noch falsche mit den "".

die('header ("Location: http://www.computerhilfen.de")');


ist das überhaupt möglich?


Gruß

Edit: Also ich habe es jetzt so gemacht die('<meta http-equiv="refresh" content="0; URL=http://www.computerhilfen.de">');

Wahrscheinlich kann ich nicht php in php machen oder? Mich würde das aber trotzdem interssieren.


exit() und die() können als Parameter nur Strings für die Fehlermeldung oder Integers für den Exit-Status entgegen nehmen (also funktioniert zumindest das mit dem header nicht). Willst du da anderes außer str und int haben (irgendwelche funktionen etc.), kannst du das davor festlegen statt in den Parameter zu setzen.

Bsp:

if(..)
{
// some code
die();
}

The_Invisible
2008-02-04, 16:22:38
Also irgendwas mache ich noch falsche mit den "".

die('header ("Location: http://www.computerhilfen.de")');


ist das überhaupt möglich?


Gruß

Edit: Also ich habe es jetzt so gemacht die('<meta http-equiv="refresh" content="0; URL=http://www.computerhilfen.de">');

Wahrscheinlich kann ich nicht php in php machen oder? Mich würde das aber trotzdem interssieren.

natürlich kannst php-code mit php generieren und ausführen, nur wird dir das bei die() oder exit() nicht helfen -> http://at2.php.net/manual/en/function.eval.php

btw
wer sagt denn das du unbedingt die() verwenden musst? du kannst statt dem die() auch ein Header("Location: ...") verwenden das sicherer wie die html variante funktioniert.

mfg

Onlinejunky
2008-02-04, 17:07:00
Hi,

das ist besser!

session_start();
if(isset($_SESSION['voteblock'])) header("Location: ../09_umfrage_der_woche/umfrage_der_woche_ban.php");
$_SESSION['voteblock'] = 1;

Habe auf jeden wall wieder einiges gelernt.

Gruß

Gast
2008-02-04, 18:21:02
Das ist falsch, du musst nach header auch noch die/exit aufrufen, sonst geht das Skript weiter.

DeX
2008-02-04, 18:44:23
Ich logge mich mal nach Monaten ein ^^ (war der Gast)

Also.. Ich habe hier mal was gemacht.

Das erlaubt dem USER nicht POST zu senden solange Form "uname" und "utext" nicht beschrieben sind.

Wenn der USER F5 drück um zu refreshen werden die 2 Forms gekillt und entleert was wieder dazu führt das kein POST ausgehen kann.

Um das ganze auch senden zu können muss man nur den Submit button als <input type="button" name="Submit" value="Send" onclick="SubmitForm(); return false;" />
anbinden.

Es entsteht keinerlei Serverlast.

window.onload = killForms;

function killForms() {
document.getElementById("uname").value = "";
document.getElementById("utext").value = "";
}

function SubmitForm() {
var form = document.forms[0];
var bR = true;
if ((form.uname.value.length < 1) || (form.utext.value.length < 1)) {
alert("Please fill out all fields.");
form.uname.value = "Your name!";
form.utext.value = "Write some stuff down here!";
bR = false;
}
if (!bR) return false;
form.submit();
}

</script>

Gut, es geht sicherlich auch sauberer. Zumindest weiß ich nicht wie deine Forms aussehen könnte man das killForms auch anders lösen. Wenn es z.B sehr viele Forms gibt, müsste man die ansonsten alle eintragen.

Onlinejunky
2008-02-04, 19:06:30
Hi,

ich habe das eigentlich wie oben schon gesagt ganz einfach gelöst.

Auf der Ergebnis Seite wird eine Session gestartet und auf "1" gesetzt.
Wenn man Refresh drückt und der Session auf "1" steht führt er einen location Header aus und verweist auf die Seite wo steht "Achtung, es darf nur einmal abgestimmt werden"

Das wars auch schon.


session_start();
if(isset($_SESSION['voteblock'])) header("Location: ../09_umfrage_der_woche/umfrage_der_woche_ban.php");
$_SESSION['voteblock'] = 1;

Das ist falsch, du musst nach header auch noch die/exit aufrufen, sonst geht das Skript weiter.

So??

ession_start();
if(isset($_SESSION['voteblock'])) header("Location: ../09_umfrage_der_woche/umfrage_der_woche_ban.php" );
exit();
$_SESSION['voteblock'] = 1;

Wenn ich das mache geht gar nix mehr!

DeX
2008-02-04, 19:25:56
Hi,

ich habe das eigentlich wie oben schon gesagt ganz einfach gelöst.

Auf der Ergebnis Seite wird eine Session gestartet und auf "1" gesetzt.
Wenn man Refresh drückt und der Session auf "1" steht führt er einen location Header aus und verweist auf die Seite wo steht "Achtung, es darf nur einmal abgestimmt werden"

Das wars auch schon.


Ist klar. Nur wozu das ganze dann noch per Server parsen? Ausser es macht dir nichts aus das Serverlast entsteht.

Naja, gut. Den Code habe ich eben selber gebraucht ^^ also wars nicht umsonst :P

Onlinejunky
2008-02-04, 19:29:57
Ne, ich danke dir ja für das Beispiel. :wink:

Jetzt habe ich aber doch noch ein Problem entdeckt.

Wenn ich ein 2. mal auf Abstimmen klicke, dann kommt zwar gleich die Meldung, dass es nicht geht aber er zählt im Hintergrund trotzdem dazu!

Hat dafür auch jemand ne Idee? Da reicht es wohl nicht aus, wenn ich nur die Location wechsel ich muss es gleichzeitig killen, das stimmt. Aber wie realisiere ich das dann genau?

gruß

creave
2008-02-04, 19:31:19
So??

ession_start();
if(isset($_SESSION['voteblock'])) header("Location: ../09_umfrage_der_woche/umfrage_der_woche_ban.php" );
exit();
$_SESSION['voteblock'] = 1;

Wenn ich das mache geht gar nix mehr!



Probiers mal so:



session_start();
if(isset($_SESSION['voteblock']))
{
header("Location: ../09_umfrage_der_woche/umfrage_der_woche_ban.php" );
exit();
}
$_SESSION['voteblock'] = 1;


Wenn es mehr als eine Anweisung im "then-Teil" gibt, brauchst du Klammern, sonst wird das exit(); immer ausgeführt, egal was bei if rauskommt.

Onlinejunky
2008-02-04, 19:45:59
Hi,

danke es geht jetzt.

Aber ist meins nicht fast das selbe wie deins??

Edit: Ok, sorry wegen den Klammern.

Kinman
2008-02-05, 08:23:21
@DeX: JavaScript sollte man nur dann einsetzen, wenns 1. nicht stört, wenns nicht läuft oder 2. wenns unabdingbar ist.

Darum ist eine Serverseitige Lösung in jeden Fall vorzuziehen.

@Onlinejunky:
http://tut.php-quake.net/
http://www.php.net/manual/de/

mfg Kinman

DeX
2008-02-05, 13:09:53
@DeX: JavaScript sollte man nur dann einsetzen, wenns 1. nicht stört, wenns nicht läuft oder 2. wenns unabdingbar ist.

Darum ist eine Serverseitige Lösung in jeden Fall vorzuziehen.

@Onlinejunky:
http://tut.php-quake.net/
http://www.php.net/manual/de/

mfg Kinman


Stimmt. Nur ist eben JavaScript perfekt mit PHP nutzbar. Ich kann doch nichts und leider alle anderen auch nichts für, dass JavaScript so missbraucht wurde. Das man es nicht nutzen sollte ist absoluter Schwachsinn. Die sollten mal JavaScrip UltraLight bringen, wo man die einfachsten Sachen noch machen kann, aber eben nicht den ganzen anderen Dreck welcher damit getrieben wird.

Ich selber habe da ja keine besonders gute Meinung.

Aber für Umfragen und Webforms kann ich mir bei besten Willen nichts besseres vorstellen als die Kombination aus PHP und JS.

Aber was er da jetzt gemacht hat ist ja sowieso der normale Weg bei PHP. Ich sag ja nichts. Anders kann man bei PHP ja nicht arbeiten als Serverseitig. :)

Onlinejunky
2008-02-05, 13:49:13
Ich denke, dass dieses kleine Session Skript nicht meinen Server in die Knie zwingen wird. :smile: Da laufen ganz andere Sachen mit PHP.

Ein großer Vorteil ist, dass man den Code nicht kopieren kann von PHP. Außerdem gibt es immer noch einige User, die aus Angst, weil eben so viel Blödsinn mit JavaScript betrieben wird, es im Browser ausschalten.

Für diese User ist so eine Website dann eine Qual. Bei unserm Kontaktformular wird auch die Abfrage erst über Javascript realisiert. Wenn jemand es aus hat, kommt PHP ins Spiel. Wenn, dann sollte man eine Hintertür haben.

Gruß

Kinman
2008-02-05, 13:57:24
Stimmt. Nur ist eben JavaScript perfekt mit PHP nutzbar. Ich kann doch nichts und leider alle anderen auch nichts für, dass JavaScript so missbraucht wurde. Das man es nicht nutzen sollte ist absoluter Schwachsinn. Die sollten mal JavaScrip UltraLight bringen, wo man die einfachsten Sachen noch machen kann, aber eben nicht den ganzen anderen Dreck welcher damit getrieben wird.

Ich selber habe da ja keine besonders gute Meinung.

Aber für Umfragen und Webforms kann ich mir bei besten Willen nichts besseres vorstellen als die Kombination aus PHP und JS.

Aber was er da jetzt gemacht hat ist ja sowieso der normale Weg bei PHP. Ich sag ja nichts. Anders kann man bei PHP ja nicht arbeiten als Serverseitig. :)

Meine persönliche Meinung ist auch sehr Pro-JavaScript. Da man einfach viele geniale Sachen machen kann. Trotzdem versuche ich allerdings wo es geht auf JavaScript zu verzichten.
Bei meinem derzeitigen Projekt würde ohne JS auch sehr vieles nicht funktionieren.

mfg Kinman

The_Invisible
2008-02-05, 18:03:47
Meine persönliche Meinung ist auch sehr Pro-JavaScript. Da man einfach viele geniale Sachen machen kann. Trotzdem versuche ich allerdings wo es geht auf JavaScript zu verzichten.
Bei meinem derzeitigen Projekt würde ohne JS auch sehr vieles nicht funktionieren.

mfg Kinman

ja, wenn man einmal mit ajax herumgespielt hat kommt man schwer wieder weg.

wichtige abfragen sollte man aber immer auch serverseitig machen da man javascript umgehen kann.

mfg