login  Naam:   Wachtwoord: 
Registreer je!
 Forum

AJAX: Tegengaan requestpagina bezoeken

Offline Voldemort - 26/08/2007 15:42 (laatste wijziging 26/08/2007 15:44)
Avatar van VoldemortPHP ver gevorderde Beste,

Als ik met AJAX een request stuur naar

www.mijnsite.com/poll_stemmen.php

dan zal dat enkel kunnen als je nog niet gestemd hebt (button die de request laat starten is enkel dan zichtbaar). Maar als iemand nu in de broncode kijkt en die vult dit in z'n adresbalk ik:

www.mijnsite.com/poll_stemmen.php

dan zal deze nogmaals kunnen stemmen.

Nu is mijn vraag:

Is er een methode om te zorgen dat enkel dmv een AJAX request die pagina aangeroepen mag worden? Of is het echt noodzakelijk om alle controles (lid ingelogd, bestaat de poll, heb je al gestemd op die poll) opnieuw te doen? Of is er een andere manier?

31 antwoorden

Gesponsorde links
Offline Ibrahim - 26/08/2007 15:56
Avatar van Ibrahim PHP expert een sessie meesturen ?
Offline Voldemort - 26/08/2007 16:00
Avatar van Voldemort PHP ver gevorderde Een sessie aanmaken in Javascript kan toch niet?
Offline Ibrahim - 26/08/2007 16:03
Avatar van Ibrahim PHP expert nee, maar AJAX werkt toch met php 
Offline Voldemort - 26/08/2007 16:06 (laatste wijziging 26/08/2007 16:07)
Avatar van Voldemort PHP ver gevorderde
  1. <input type="button" name="submit" value="Stemmen" onclick="verwerk('http://www.mijnsite.com/poll_verwerk.php')" />


Dus ik moet een sessie aanmaken als er op de button geklikt en op http://www.mijnsite.com/poll_verwerk.php controleren of deze sessie wel degelijk bestaat. Nu vormt het aanmaken van die sessie een probleem omdat de button Javascript meteen activeert en er dus geen tijd is voor nog PHP.
Offline Stijn - 26/08/2007 16:11
Avatar van Stijn PHP expert in poll_verwerk.php moet je die sessie maken. Zo moet je poll_verwer.php eruit zien:

  1. if( isset( $_SESSION['voted'] ) && $_SESSION['voted'] == 1 ) {
  2. echo 'sorry, je kan maar één keer stemmen';
  3. } else {
  4. //de hele vote verwerking code
  5.  
  6. //vergeet niet om $_SESSION['voted'] = 1; te doen als de verwerking compleet is.
  7. }
Offline Voldemort - 26/08/2007 16:16
Avatar van Voldemort PHP ver gevorderde Maar als men dan de browser afsluit is de sessie weg en kan met nog steeds / opnieuw het trucje uithalen. Dus ik denk dat dit geen goede oplossing is. Is er dus een andere oplossing? Of zie ik wat over het hoofd?
Offline EXcium - 26/08/2007 16:18
Avatar van EXcium Lid IP in de database opslaan?
Offline Voldemort - 26/08/2007 16:20
Avatar van Voldemort PHP ver gevorderde Dan zit ik weer met controlequeries en die wil ik nu net vermijden.
Offline Grayen - 26/08/2007 17:27
Avatar van Grayen PHP ver gevorderde Zou je niet iets met headers kunnen doen. Ik heb geen flauw idee, maar misschien verschilt er iets aan de headers die mee worden gestuurt als AJAX een request uitvoert, of als je er rechstreeks heen gaat?
Offline Stijn - 26/08/2007 17:33
Avatar van Stijn PHP expert Voldermort, denk eens logisch na. Wat bewaard data langer dan een sessie.... idd een cookie en als je wilt dat het echt uniek wordt moet je met mysql werken en/of leden.
Offline Voldemort - 26/08/2007 18:03
Avatar van Voldemort PHP ver gevorderde @Grayen: Geen idee. En daarbij kan men door snel even een programmaatje te schrijven de headers zelf bepalen (ok, er zijn niet velen die het ook echt zullen doen, maar je hebt er altijd die zo zot zijn het te doen).

@Stijn: Een cookie kan men verwijderen. Zal dus inderdaad toch database worden (controle of je de poll bestaat en daarna controle of je reeds gestemd hebt).
Offline ikki007 - 26/08/2007 18:06
Avatar van ikki007 Gouden medailleGouden medaille

PHP ver gevorderde
Als je geen cookie of sessie wil moet je met controle queries werken.
Offline Stijn - 26/08/2007 18:55
Avatar van Stijn PHP expert Of met een bestand waarin je het ip adres met een sperator key scheidt en dan gewoon controleert of het ip in het bstand staat.
Offline Voldemort - 26/08/2007 20:05
Avatar van Voldemort PHP ver gevorderde Het waren nu net die 2 dingen die ik wou proberen voorkomen:

- Geen extra data wegschrijven, niet naar de database en niet naar een bestand.
- Geen queries om dingen te controleren (Bestaat de poll wel? Heb je al gestemd?).

Maar aangezien het niet mogelijk is te controleren of de request van AJAX komt of dat de bezoeker het url in z'n adresbalk heeft ingevuld zonder gebruik te maken van 1 van deze 2 technieken heb ik gebruik gemaakt van de 2e.

----------------------------------------------------------------

Ik zat echter wel te denken aan dit:

Een random getal generen met Javascript tussen 1 en 1 000 000 000 000. Dan doe ik een request naar sessie.php die de key in een sessie stopt. Dan doe ik pas de request naar poll_verwerk.php (waarbij ik de key ook meestuur) en die controleert:

1) Bestaat de sessie?
2) Zoja, heeft de sessie de correcte waarde (vergelijkt de sessiewaarde met de meegestuurde waarde).
3) Zoja, dan is de request dmv AJAX gebeurt.

Is dit een veilige methode?
Offline Gerard - 26/08/2007 20:29
Avatar van Gerard Ouwe rakker Maak een 'pollvote' een samengestelde sleutel van het pollid en de userid. Op die manier kan iemand nooit 2 keer stemmen op dezelfde poll omdat je dan 2 dezelfde primary keys hebt.

Wat betreft het "bestaat de poll wel" moet je dat gewoon controleren.
Offline Voldemort - 27/08/2007 09:36 (laatste wijziging 29/08/2007 10:13)
Avatar van Voldemort PHP ver gevorderde @Proximus: Die pollvote, dat is dan een primair key veld in de database?

Is mijn idee (vorige post) eigenlijk goed?
Offline Grayen - 27/08/2007 10:34 (laatste wijziging 27/08/2007 10:36)
Avatar van Grayen PHP ver gevorderde Nee, want dan zouden ze toch naar session.php kunnen gaan (ik neem aan dat je gegevens doorstuurt met een $_GET) en daar bijvoorbeeld session.php?key=101010 en dan hebben ze die sessie. Vervolgens gaan ze naar poll_verwerk.php?key=101010 en voila we kunnen gewoon stemmen . En wat de key is kunnen ze achterkomen door in de source te kijken. Kun je niet gewoon verbieden dan men rechtstreeks naar die bestanden gaat (denk aan .htaccess)?

Nog een mogelijkheid is proberen gebruik te maken van $_POST, die kunnen ze namelijk alleen doormiddel van een formulier creëren en als jij als ze al gestemd hebben ze geen formulier laat zien kunnen ze moeilijk nog eens stemmen.
Offline Voldemort - 27/08/2007 14:23 (laatste wijziging 27/08/2007 14:29)
Avatar van Voldemort PHP ver gevorderde @Grayen: Je snapt het niet. Ik bedoel dit:

Javascript:
  1. //Random key genereren
  2. Math.floor(Math.random()*1000000000000);


AJAX POST request met bovenstaande gegenereerde key naar sessie.php

PHP:
Sessie.php ==> Kijk of er een key is meegestuurd. Zoja, maak de sessie met als value de key. Maak ook een cookie met de key. Over beide dient wel md5 en sha1 gegooit te worden.

Javascript:
AJAX request naar poll_verwerk.php

PHP:
poll_verwerk.php ==> Controleren of de sessie bestaat en gelijk is aan de waarde van de cookie. Aan het einde de sessie legen.

Maar het probleem hierbij is dat je dmv de source (het genereren van de key) en de cookie (gehashte waarde) een scriptje kan maken dat de md5 en sha1 van 1 tot 1 000 000 000 000 afgaat en die controleert met de cookie.

Deze optie kan dus niet. Is er geen andere optie?


Dat van die .htaccess vroeg ik me ook af. Ik denk van niet want JS laat dat bestand openen en aangezien JS client-side is, zal Apache dit behandelen als een nieuwe pagina die geopend wordt en niet als iets aparts. Dit DENK ik, mocht ik fout zijn en het inderdaad kunnen, laat het me dan weten.
Offline Grayen - 27/08/2007 14:50
Avatar van Grayen PHP ver gevorderde Ik denk dat het het verstandigst is om gewoon te gaan werken met een extra query, want over hoeveel tijd hebben we het? 0,003 sec? Ik denk dat deze hele omweg meer tijd zal gaan kosten dan het uitvoeren van een enkele simpele query .
Offline Stijn - 27/08/2007 14:51
Avatar van Stijn PHP expert Je maakt het ietswat ingewikkeld. Ik weet niet wat de benchmarks zijn voor een ajax request naar een mysql server maar volgens mij duurd dit evenlang als je geen ajax zou gebruiken.
Offline Voldemort - 27/08/2007 15:14
Avatar van Voldemort PHP ver gevorderde Ok, dan doe ik het met 1 extra query. Hoe doe ik dat dan het beste volgens jullie?
Offline Stijn - 28/08/2007 16:21
Avatar van Stijn PHP expert Ik zal eens zelf testen maar ik dacht zo dat je via $_SERVER['REQUEST_URI'] kijken of de URL in de adresbalk is ingevuld. Je moet dan na een succesvolle request in javascript die knop waarmee je kan voten uitschakelen anders kan met 2 of meerdere keren stemmen.

Hoe ook rekening met browsers waar JS is uitgeschakeld.
Offline Voldemort - 29/08/2007 10:12
Avatar van Voldemort PHP ver gevorderde $_SERVER['REQUEST_URI'] werkt niet, die geeft gewoon /dirs/poll_verwerk.php terug.
Offline ArndJan - 29/08/2007 10:20 (laatste wijziging 29/08/2007 10:22)
Avatar van ArndJan PHP interesse Wat doen we moeilijk?

  1. <?php
  2.  
  3. // index.php is de pagina waarvandaan het request word verzonden.
  4.  
  5. if(stristr($_SERVER['HTTP_REFERER'], 'index.php'))
  6. {
  7. # Poll updaten...
  8. } else
  9. {
  10. # hack
  11. }
  12.  
  13. ?>


De code kijkt even of het request wel van de goede pagina afkomt en daarna kun je een actie uitvoeren, en anders kun je alle bewerkingen afbreken.

 
Offline Voldemort - 29/08/2007 10:27 (laatste wijziging 29/08/2007 10:30)
Avatar van Voldemort PHP ver gevorderde Kan je dan niet dit proberen:

- Ga naar de poll.php pagina (waar het stemformulier staat).
- Ga daarna naar de poll_verwerk.php pagina.

Dan zal de REFERER toch ook poll.php zijn? Of ben ik nu fout?

Edit: Op php.net:

Citaat:
The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.


Niet veilig dus.
Offline ArndJan - 29/08/2007 10:52
Avatar van ArndJan PHP interesse Dan maak je zelf iets...

  1. <?php
  2.  
  3. // op elke pagina
  4.  
  5. $_SESSION['pagina'] = $_SERVER['PHP_SELF'];
  6.  
  7. ?>
  8. -----
  9. <?php
  10.  
  11. if(stristr($_SESSION['pagina'], 'index.php'))
  12. {
  13. # Poll updaten...
  14. } else
  15. {
  16. # hack
  17. }
  18.  
  19. ?>
Offline Voldemort - 29/08/2007 11:24
Avatar van Voldemort PHP ver gevorderde Dan kan men nog steeds hetzelfde trucje uithalen. Eerst naar de poll.php pagina (sessie krijgt de correcte waarde) en dan naar poll_verwerk.php (sessie heeft dan ook die correcte waarde).
Offline ArndJan - 29/08/2007 12:05
Avatar van ArndJan PHP interesse Misschien koppelen aan een ip?

Is een poll zo belangerijk? Dan moet je misschien een andere manier verzinnen zodat je het wel kan doen...
Offline Voldemort - 29/08/2007 20:41
Avatar van Voldemort PHP ver gevorderde Koppelen aan IP: Hoe moet ik dat dan doen? Vanals men op de button klikt wordt er meteen Javascript uitgevoerd (onclick), dus ik zou 2 requests moeten doen, maar dan kan men alsnog naar beide pagina's gaan.

Die poll is misschien niet zo belangrijk, maar als ik in andere onderdelen ook AJAX ga gebruiken wil ik niet dat iedereen door naar dat url te gaan een wijziging kan doen.

Dus hoe kan het dan wel?
Offline Grayen - 29/08/2007 23:45
Avatar van Grayen PHP ver gevorderde Ik heb lopen nadenken over jouw probleem en het enige antwoord waarop ik telkens kom is dat je persee die controlles moet uitvoeren. Want wat je met AJAX doet, moet je zien alsof jij een pagina bezoekt, alleen doet in dit geval de browser het. Bezoek jij een pagina op jouw site, dan worden ook eerst al deze controles uitgevoert, dus deze controles moeten ook worden uitgevoerd op de pagina die ajax voor je bezoekt. Je moet dus in gedachte houden dat de pagina die de browser voor je bezoekt gewoon exact hetzelfde is alsof jij een pagina zou bezoeken. De controles zijn dus noodzakelijk vanwege veiligheid van je site.
Gesponsorde links
Dit onderwerp is gesloten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.23s