[PHP] Webcounter met reload beveiliging

Pagina: 1
Acties:
  • 111 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb een simpele webcounter gemaakt in php, die het aantal bezoekers bijhoud in een bestand.

Nu wil ik graag ervoor zorgen dat er een reload beveiliging op komt. Oftewel, hij moet de counter niet verhogen als je op refresh/reload/F5 klikt...

Nu heb ik al een tijdje aan het zoeken op internet, maar kan daar geen oplossing vinden.
Weet iemand een oplossing?

Acties:
  • 0 Henk 'm!

  • Gertjan
  • Registratie: Oktober 2001
  • Laatst online: 09-09 17:11

Gertjan

mmmm, beer...

- IP-adres van bezoeker opslaan (werkt niet optimaal als bezoeker gebruik maakt van proxy)
- cookie plaatsen bij gebruiker
- etc ...

[ Voor 24% gewijzigd door Gertjan op 18-01-2006 16:11 ]


Acties:
  • 0 Henk 'm!

  • Bud_s
  • Registratie: Maart 2002
  • Laatst online: 20-09 16:55

Bud_s

Team Anticimex & Lock

kijk eens naar de SESSION_ID

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Moet de topicstarter uiteraard eerst wel gebruik maken van sessies. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Is dit niet gewoon een script request voor t maken van een webcounter? :? Lijkt me bijzonder goed zelf uit te vinden hoe je unieke bezoekers identificeerd.

Acties:
  • 0 Henk 'm!

  • DumbAss
  • Registratie: April 2002
  • Laatst online: 16-08 11:30
Is het geen optie om te kijken of de referrer pagina hetzelfde is als de huidige pagina? Dan heeft iemand klaarblijkelijk op f5 geduwd... Of zeg ik nu iets heel stoms?

Vanutsteen.nl => nerds only | iRacing


Acties:
  • 0 Henk 'm!

  • sjhgvr
  • Registratie: Januari 2004
  • Laatst online: 04-08 14:27
ahhh, hier stond poep

[ Voor 92% gewijzigd door sjhgvr op 18-01-2006 16:43 ]

oisd.nl


Acties:
  • 0 Henk 'm!

  • gertvdijk
  • Registratie: November 2003
  • Laatst online: 18-09 11:40
Het handigste lijkt mij het inderdaad te doen met gebruik van sessions.
Je moet de betreffende pagina onmiddelijk starten met session_start(); PHP heeft zo de mogelijkheid de headers betreffende de sessie alvast de deur uit te doen, omdat dit later (na 1 karakter html) niet meer mogelijk is.
Je kijkt vervolgens met $sessienummer = session_id(); de random gegenereerde nummers gaan vergelijken.
Na opnieuw opstarten van de browser of het verlopen van sessietijd wordt meestal een nieuwe sessie aangemaakt.

Kia e-Niro 2021 64 kWh DynamicPlusLine. See my GitHub and my blog for articles on security and other stuff.


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

m.a.w. iets simpels als

PHP:
1
2
3
4
5
session_start ();
if (!isset ($_SESSION['counted'])) {
   updateCounter();
   $_SESSION['counted'] = 1;
}

Acties:
  • 0 Henk 'm!

  • gertvdijk
  • Registratie: November 2003
  • Laatst online: 18-09 11:40
^^ nog makkelijker ;)

Kia e-Niro 2021 64 kWh DynamicPlusLine. See my GitHub and my blog for articles on security and other stuff.


Acties:
  • 0 Henk 'm!

Verwijderd

Jullie gaan er vanuit dat TS sessions wil/kan gebruiken.
Wat als dit niet zo is? Een oplossing is de volgende;

Initialiseren
PHP:
1
2
3
4
// init
$dir = $_SERVER['DOCUMENT_ROOT'].'/map/bla/bla/';
$fname = 'counter.inc';
$x_period = "1 SEC";    // <-   whatever you want, see php's strtotime()


Maak een opslagbestand aan of open de reeds bestaande
PHP:
1
2
3
4
// init (create?) counter file
if(!$fp = fopen($dir.$fname, "a+")) {
    $error = true;
}


Vervolgens ga je kijken of er al data (een line) van de bezoeker in het bestand voorkomt.
False) Als dit niet zo is, dan is het simpel: je maakt een nieuwe lijn aan met informatie over de gebruiker.
Je slaat de volgende data op: het ip-adres, het aantal visits (1) en de huidige tijd. Dit alles #-gescheiden + een new line character, bijv.
196.12.24.101#1#1137604676\r\n
True) De bezoeker bestaat al in je bestand, dus ga je kijken of de bezoeker de pagina bezocht heeft binnen de tijd die jij er voor gezet hebt (zie variabele `x_period`). Als dat wél zo is, doe je niets, als dat níet zo is dan moet het aantal visits van de bezoeker verhoogt worden met één. Dit doe je door de gehele lijn van de bezoeker te vervangen door exact dezelfde lijn, echter met het aantal visits verhoogd met één. Ofwel:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
if(!isset($error)) {

    $content = file_get_contents($dir.$fname);

    // collect visitor data
    $ip = $_SERVER['REMOTE_ADDR'];
    $curtime = time();
    $regexp = "/".$ip."#[0-9]+#[0-9]{10}/";

    // current visitor (=ip) already exists in file?
    $exists  = preg_match($regexp, $content, $matches) == 1 ? true : false;

    // increase counter?
    switch($exists) {
        case false:
            // create new line for this new visitor
            fwrite($fp, $ip."#1#".$curtime."\r\n");
        break;
        case true:
            // check or this visitor
            // visited this page within the 
            // x-period of time. If not,
            // increase visitors ammount.
            $data = explode("#", $matches[0]);          
            if($data[2] < strtotime("-".$x_period)) {
                $data[1]++;
                $data[2] = $curtime;
                $newline = implode("#", $data);
                $upd_fp = fopen($dir.$fname, "w");
                fwrite($upd_fp, preg_replace($regexp, $newline, $content));
                fclose($upd_fp);
            }
        break;
    }
    fclose($fp);

}


Vervolgens maak je nog een hyper-mega-superknots functie die voor je gaat tellen hoeveel hits er geweest zijn (en hits wil in dit geval zeggen, het aantal bezoekjes aan je pagina zonder dat een gebruiker die binnen de tijd `x_period` terugkwam meegerekend wordt). Zie hier:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
// function to collect visitor ammounts
// (vars `dir` and `fname` must be defined)
function hits() {
    global $dir, $fname;
    if($file = file($dir.$fname)) {
        preg_match_all(
                "/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+#([0-9]+)#[0-9]{10}/",
                file_get_contents($dir.$fname),
                $matches
        );
        return array_sum($matches[1]);
    }
}


Het kan allemaal efficienter qua coding, maar het is een werkend voorbeeld.. :Y)

[ Voor 5% gewijzigd door Verwijderd op 18-01-2006 18:25 ]


Acties:
  • 0 Henk 'm!

  • pietje63
  • Registratie: Juli 2001
  • Laatst online: 16:14

pietje63

RTFM

Verwijderd schreef op woensdag 18 januari 2006 @ 18:25:
Jullie gaan er vanuit dat TS sessions wil/kan gebruiken.
Kan dat niet altijd met php dan?

De grootste Nederlandstalige database met informatie over computers met zoekfunctie!!


Acties:
  • 0 Henk 'm!

Verwijderd

pietje63 schreef op woensdag 18 januari 2006 @ 18:31:
[...]

Kan dat niet altijd met php dan?
Het kan zijn dat door beveiligingsinstellingen de bezoeker geen gebruik kan maken van de sessions, afhankelijk van hoe e.e.a. ingesteld is op de webserver van de applicatie. En waarom voor iets simpels als dit het risico nemen dat jouw counter niet goed functioneert en nog belangrijker, waarom de functionaliteit van jouw counter afhankelijk laten zijn van de instellingen van de bezoeker?

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op woensdag 18 januari 2006 @ 18:25:
Jullie gaan er vanuit dat TS sessions wil/kan gebruiken.
Wat als dit niet zo is? Een oplossing is de volgende;
Dat is dus zeker geen oplossing, want niet multi-user. Kenmerk van een site is dat het multi-user moet zijn.

Wat als er 10 nieuwe gebruikers tegelijkertijd je site bezoeken? Dan krijg je 10 processen die tegelijk naar hetzelfde bestand willen schrijven. Lijkt me niet echt een ideale oplossing.

Acties:
  • 0 Henk 'm!

  • gertvdijk
  • Registratie: November 2003
  • Laatst online: 18-09 11:40
Verwijderd schreef op woensdag 18 januari 2006 @ 18:47:
[knip]
Wat als er 10 nieuwe gebruikers tegelijkertijd je site bezoeken? Dan krijg je 10 processen die tegelijk naar hetzelfde bestand willen schrijven. Lijkt me niet echt een ideale oplossing.
Eens. Bovendien werkt het niet als er hordes bezoekers achter één proxy zitten. Chello configureert/configureerde in ieder geval zijn eigen proxy server in IE en ook op veel instellingen/werkplekken surft men via proxy's.

PHP:
1
$ip = $_SERVER['REMOTE_ADDR'];

Zo verkrijg je dus de proxy server als een gebruiker achter een proxy zit.
Verwijderd schreef op woensdag 18 januari 2006 @ 18:25:
Jullie gaan er vanuit dat TS sessions wil/kan gebruiken.
[knip]
Volgens mij geeft jouw voorbeeld juist aan dat gebruik van sessions dè manier is. Hoewel jouw script ook gelijk de hits wegschrijft, is het principe veel ingewikkelder en vereist volgens mij een hoger niveau van de programmeur.

Mochten er bezoekers zijn die browsen zonder ondersteuning van sessions dan kunnen ze niet veel surfen op Internet. Veel websites vertrouwen op de werking van sessions. Denk aan winkelmandjes bij internetwinkels of een forum.

[ Voor 32% gewijzigd door gertvdijk op 18-01-2006 19:16 ]

Kia e-Niro 2021 64 kWh DynamicPlusLine. See my GitHub and my blog for articles on security and other stuff.


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
Verwijderd schreef op woensdag 18 januari 2006 @ 18:47:
Wat als er 10 nieuwe gebruikers tegelijkertijd je site bezoeken? Dan krijg je 10 processen die tegelijk naar hetzelfde bestand willen schrijven. Lijkt me niet echt een ideale oplossing.
Zeer waar. Zelf ook ooit eens problemen mee gehad met een eigen scripseltje op een site die een paar duizend pageviews per dag trok.. Teller kwam zelden hoger dan ~700 pageviews voor het bestand weer stuk ging :)

Anyway, sessie's of een referrer check zijn eigenlijk de enige gangbare oplossingen, en ja die zijn allebij afhankelijk van de client. Maar zoals gezegd, die paar pageviews die je extra krijgt doordat iemand sessies uit heeft staan zul je niet snel missen :) Maw, lekker Bosmonsters script gebruiken ;)

offtopic:
gertvdijk, je weet hopelijk wel dat er regular expressies zijn voor zowel het aangeven van een cijfer als het aangeven dat er 5 van achter elkaar moeten staan? :X En een switch met enkel true of false is een beetje overkill IMHO ;)

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • gertvdijk
  • Registratie: November 2003
  • Laatst online: 18-09 11:40
FragFrog schreef op donderdag 19 januari 2006 @ 05:01:
offtopic:
gertvdijk, je weet hopelijk wel dat er regular expressies zijn voor zowel het aangeven van een cijfer als het aangeven dat er 5 van achter elkaar moeten staan? :X En een switch met enkel true of false is een beetje overkill IMHO ;)
Ik weet heel goed wat regular expressions zijn en ik kan ze ook gebruiken, maar ik begrijp niet wat je bedoelt.

Kia e-Niro 2021 64 kWh DynamicPlusLine. See my GitHub and my blog for articles on security and other stuff.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Verwijderd schreef op woensdag 18 januari 2006 @ 18:36:
Het kan zijn dat door beveiligingsinstellingen de bezoeker geen gebruik kan maken van de sessions, afhankelijk van hoe e.e.a. ingesteld is op de webserver van de applicatie. En waarom voor iets simpels als dit het risico nemen dat jouw counter niet goed functioneert en nog belangrijker, waarom de functionaliteit van jouw counter afhankelijk laten zijn van de instellingen van de bezoeker?
Als de beveiligingsinstellingen zo ingesteld staan dat cookies niet mogelijk zijn (sessies zijn immers voor een gebruiker gewoon cookies), dan wordt bij de standaardinstellingen van PHP automatisch een GET-variabele gemaakt en automatisch bij de querystring erbij geplakt, AFAIK. Je argument om op een foutgevoelige manier naar een file te gaan schrijven gaat dus niet helemaal op. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Ik ben met alle doe-het-niet-op-de-Ivy-manier argumenten eens, maar wat ik probeerde aan te tonen is dat je prima zónder gebruik van sessies een unique visitor systeem kan maken.
Alle aftakkingen van deze discussie, bijvoorbeeld de stelling `dat een bezoeker zonder sessies niet lekker kan surfen` staan daar natuurlijk compleet los van lijkt me.
Nogmaals, ik probeerde aan te tonen dat het ook zonder sessies kan, en dat kan dus.

De enigste twee noemenswaardige nadelen zijn de volgende.

- Het ip-adres wordt té gemakkelijk verkregen in mijn voorbeeld. Ik kan niets anders zeggen dan dat dit waar is. Maar hier zijn wel degelijk oplossingen voor te vinden (ik zag laatst ergens een topic voorbij komen waarin uitgelegd werd hoe je iemand zijn netwerk-ipadres kunt verkijgen), of kun je een gebruiker op andere manieren uniek maken (door andere gegevens van hem of haar te verzamelen en deze te combineren tot een unieke string (combinatie van ip-adres, operating-sys., beeldschermresolutie, etc. etc.). Om daar gelijk het heel script en de methode op af te kraken lijkt me dus niet terecht.

- Dan het probleem dat het databestand niet tegelijk geopend kan worden door meerdere bezoekers binnen een fractie van een seconde. Ook hier zijn natuurlijk diverse oplossingen voor te bedenken.

Kortom, helemaal in de prullenbak hoeft het scriptje, en de gedachte tot het maken ervan, niet te verdwijnen vindt ik. Met wat diepgang werkt het zelfs perfect en @ -NMe-, zoals je ziet zijn de foutjes netjes weg te werken, toch? Het zou erg (lees: nog meer) offtopic gaan om in te gaan op de manieren die er te bedenken zijn voor prefentie van het dubbel-openen van het databestand, maar die manieren zijn er wel degelijk - rest mij te melden dat de ideetjes die ik zo af en toe rondslinger hier op GoT zeker niet perfect zijn, heb nog meer te doen nl.. ;)

Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Lees anders de reply van [rml]-NMe- in "[ PHP] Webcounter met reload beveiliging"[/rml] nog eens :)

PHP heeft daar al een fail-safe voor :) Lijkt me juist handiger om niet opnieuw het wiel uit proberen te vinden.

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

Verwijderd

BtM909 schreef op donderdag 19 januari 2006 @ 18:48:
Lees anders de reply van [rml]-NMe- in "[ PHP] Webcounter met reload beveiliging"[/rml] nog eens :)

PHP heeft daar al een fail-safe voor :) Lijkt me juist handiger om niet opnieuw het wiel uit proberen te vinden.
Met alle respect, maar als ik alles wat ik op een dag lees dubbel moet lezen dan zou ik een dagdeel tekort komen in een etmaal :Y)

/offtopic

En zo verkeerd is mijn reservewiel idee toch niet?

[ Voor 8% gewijzigd door Verwijderd op 20-01-2006 10:11 ]


Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

FragFrog schreef op donderdag 19 januari 2006 @ 05:01:
... Teller kwam zelden hoger dan ~700 pageviews voor het bestand weer stuk ging :)
Gelukkig kan je files zo makkelijk locken, zodat ze niet kapot kunnen gaan :)

Acties:
  • 0 Henk 'm!

Verwijderd

Op sommige systemen is flock() geﭰlementeerd op proces hoogte. Wanneer je dan een multithreaded server API gebruikt zoals ISAPI, dan kan je er mogelijk niet van uitgaan dat flock() bestanden beschermd van andere PHP scripts die in parallele threads draaien op dezelfde server instantie!
Maar goed, dat is 'op sommige systemen'. Hoe dan ook, wat als het ding gelocked is maar niet meer unlocked wordt? Plus, dat klant 99 moet wachten tot klant 56 het bestand weer vrijgeeft, lijkt me ook niet echt een ideale situatie.

Bestanden op het FS gebruiken voor een counter, is gewoon bad practice. Sure, met een heleboel truukjes en workarounds is het best werkende te krijgen, maar imo moet je dat niet willen.

Je kunt dan beter naar een database-oplossing gaan kijken, of - nog beter - gewoon sessies gebruiken. Er zijn tonnen websites die het toestaan van sessies eisen, imo is dat een redelijke eis.

[ Voor 52% gewijzigd door Verwijderd op 20-01-2006 13:55 ]


Acties:
  • 0 Henk 'm!

  • Metalman
  • Registratie: December 2003
  • Laatst online: 16:56
eamelink schreef op vrijdag 20 januari 2006 @ 13:25:
[...]


Gelukkig kan je files zo makkelijk locken, zodat ze niet kapot kunnen gaan :)
Maar dat maakt het script nog niet multi-user. Dan staan alle bezoekers in feite op elkaar te wachten tot ze een entry in de logfile krijgen. Ook niet echt ideaal lijkt me.
Ikzelf zou gaan voor een database gedreven oplossing, i.c.m. sessies om te voorkomen dat bij elke pageview van een bezoeker een nieuw record aangemaakt wordt.

[ Voor 17% gewijzigd door Metalman op 20-01-2006 13:37 ]

Pagina: 1