Autor | Zpráva | ||
---|---|---|---|
Eflyax Profil |
#1 · Zasláno: 11. 3. 2011, 20:18:40
Ahoj,
Potřeboval bych pomoct s automatickým odhlašováním ve své webové aplikaci. Přihlašování a odhlášení (provedené uživatelem) mi funguje. Problém je v tom, že: - nemám k dispozici SQL databázi (Aplikaci využíváme na intranetu bez přístupu na internet - k sql nemám přístup) - na serveru nejsou povoleny globální proměnné (nevím jestli to to s tím nějak souvisí) Po přihlášení uživatele se jeho jméno zapíše do textového souboru (databáze online uživatelů), až on sám klikne na Odhlásit se, je z té databáze (texťáku) vymazán. Potřebuji tedy vyřešit, jak ho z toho textového souboru vymazat, například při nečinnosti 10 minut. Nevím jestli by třeba nešlo využít platnost session tak, aby po vypršení platnosti se vykonal nějáký příkaz. Zkoušel jsem využít i javascript, přesněji událost onUnload ale uživatel je odhlášen i při procházení mezi stránkami. Mockrát děkuji za pomoc. |
||
snake.aas Profil |
#2 · Zasláno: 11. 3. 2011, 20:24:35
ukládat si i čas a porovnávat? ale to je řešení pro malé množství uživatelů...
mimochodem: hrozně rád bych ten kód viděl, jen moje zvědavost, mohl bys? |
||
Eflyax Profil |
#3 · Zasláno: 11. 3. 2011, 20:56:38 · Upravil/a: Eflyax
Ano, není problém :)
zde je login.php (zpracování jména a hesla z formuláře): <?php session_start(); $Njmeno = $_POST['jmeno']; $Nheslo = $_POST['heslo']; setcookie("uzivatel", "$Njmeno", time()+86400); if (($Njmeno == "jmeno1" && $Nheslo == "heslo1") || ($Njmeno == "jmeno2" && $Nheslo == "heslo2") || ($Njmeno == "jmeno3" && $Nheslo == "heslo3") || ($Njmeno == "jmeno4" && $Nheslo == "heslo4") ) { $_SESSION['authuser'] = 1; header("HTTP/1.1 301 Moved Permanently"); header("Location: index.php"); header("Connection: close"); $staryobsah = file_get_contents("online.txt"); $soubor = fopen("online.txt", "w+"); fwrite($soubor, "$Njmeno \n$staryobsah" ); fclose($soubor); // zde se otevře texťák a zapíše se na začátek dokumentu jeho jméno -> to právě potřebuji zase smazat při neaktivitě } ?> A zde je kód pro odhlášení (které provede sám uživatel): <?php session_start(); $_SESSION['authuser'] = 0; $jméno = $HTTP_COOKIE_VARS["uzivatel"]; $staryobsah = file_get_contents("online.txt"); $soubor = fopen("online.txt", "w"); $obsahBezjména = Str_Replace ("$jméno \n", "", "$staryobsah"); //vymazání jména odhlašovaného z texťáku fwrite($soubor, "$obsahBezjména" ); fclose($soubor); echo "Jsi úspěšně odhlášen! \n<br>"; echo "Nyní pokračuj na hlavní stranu: <a href='../'>Jít na hlavní stránku</a>"; ?> <?php exit(); ?> Vše mi funguje bez problémů . Aplikaci využívá cca. 15 - 20 lidí. S tím ukládáním času a porovnáváním si ale nevím rady :-( |
||
Seith Profil |
#4 · Zasláno: 11. 3. 2011, 21:36:07
Ověřuješ na nějaké stránce, je-li uživatel přihlášen? Nebo máš v texťáku pouze pro informaci kdo je přihlášen?
|
||
Eflyax Profil |
#5 · Zasláno: 11. 3. 2011, 22:28:07
Ano, ověřuji. Při úspěšném přihlášení se uživateli nastavi session authuser na 1. Tato session je na každé stránce kontrolována. Odhlášením se vymaže jméno uživatele z texťáku a nastavi se session na 0 - je odhlášem.
|
||
Seith Profil |
#6 · Zasláno: 12. 3. 2011, 21:15:41
Tak si do session ulož při přihlášení i čas, kdy se přihlásil - např. pomocí fce time(). Na každé další stránce, kde se kontroluje je-li přihlášen, přidej ještě kontrolu času ze session (čas v session > time()-60*10 (pro 10 minut)). Pokud je větší, zaktualizuj údaj v session o čase. Pokud tomu tam není, znamená to, že uživatel byl déle než 10 minut neaktivní, tj. odhlaš ho. Psal jsem to hodně obecně, pokud něco nechápeš, napiš.
|
||
Eflyax Profil |
#7 · Zasláno: 13. 3. 2011, 08:50:12 · Upravil/a: Eflyax
Tohle chápu, děkuji. Je ale možné po vypršení platnosti vymazat uživatele z textového souboru?
Myslím, že to nejde. Není třeba jiná možnost jak udělat online stav uživatelů? Například výpis aktivních session? Dále jsem ještě zkoušel přes javascript událost onunload - při odchodu chci uživatele přesměrovat, bohužel se to nestihne přesměrovat. Koukám, že bez SQL to asi nepůjde. |
||
Radovan789 Profil * |
#8 · Zasláno: 13. 3. 2011, 10:24:00
Eflyax:
Koukám, že bez SQL to asi nepůjde. Proč by to nešlo ? Stačí udělat to co napsal Seith. Pak to může vypadat nějak takhle: <?php session_start(); if ($_SESSION['time'] > time()-60*10 AND $_SESSION['authuser'] == 1) { // A tady budeš mít kód který se provede v případě že uživatel bude 10 minut neaktivní. $_SESSION['authuser'] = 0; $jméno = $HTTP_COOKIE_VARS["uzivatel"]; $staryobsah = file_get_contents("online.txt"); $soubor = fopen("online.txt", "w"); $obsahBezjména = Str_Replace ("$jméno \n", "", "$staryobsah"); //vymazání jména odhlašovaného z texťáku fwrite($soubor, "$obsahBezjména" ); fclose($soubor); echo "Jsi úspěšně odhlášen! \n<br>"; echo "Nyní pokračuj na hlavní stranu: <a href='../'>Jít na hlavní stránku</a>"; } ?> |
||
Seith Profil |
#9 · Zasláno: 13. 3. 2011, 10:36:43 · Upravil/a: Seith
Radovan789:
„Pak to může vypadat nějak takhle:“ Ještě bych asi rozdělil podmínku a informoval uživatele co je špatně, ale to už je věc návrhu. Každopádně ještě nezapomeň (to je mířené spíš Eflyaxovi) na zaktualizování času v session pokud prošel kontrolou, jinak ho to odhlásí za 10 minut od přihlášení, což nechceme. |
||
Radovan789 Profil * |
#10 · Zasláno: 13. 3. 2011, 10:48:39
Seith, Eflyax:
Taky problém je vtom, když uživatel zavře prohlížeč, tak ho to naodhlásí a zůstane zapsán v souboru, což nechceme. Takže se to bude muset vyřešit přes CRON. |
||
Seith Profil |
#11 · Zasláno: 13. 3. 2011, 10:56:18
Radovan789:
„Taky problém je vtom, když ... vyřešit přes CRON.“ To je pravda, nakonec se nevyhneme tomu, ukládat do textového souboru jméno i čas. Díky tomu bude asi nejlepší možnost ověřovat přihlášení uživatele čístě pomocí existence zápisu v souboru. |
||
Seith Profil |
#12 · Zasláno: 13. 3. 2011, 11:24:23
Eflyax:
Máš přístup k nastavení CRON? Pokud ano, napsal bych ti nějaké řešení. |
||
Seith Profil |
#13 · Zasláno: 13. 3. 2011, 12:17:47 · Upravil/a: Seith
Eflyax:
Mám dobrou náladu, tak jsem napsal přihlašování, kontrolu a odhlašování. Neřeší to problém na který poukázal Radovan789. Pokud máš na serveru přístup ke CRONu, ještě bych ti napsal script, kterej jednou za čas odstraní "prošlé" záznamy, anebo pokud uživatelů není moc (což předpokládám) a ty pravděpodobně chceš obsah souboru online.txt vypisovat (jinak by jsme ho neoužívali), nemusíme odstraňovat staré záznamy, pouze je při výpisu nevypíšeš. soubor online.txt má strukturu: jmeno:cas_posledni_aktivity;dalsi_jmeno:dalsi_cas_posledni_aktivity ... prihlaseni.php: <?php $Njmeno = $_POST['jmeno']; $Nheslo = $_POST['heslo']; if (($Njmeno == "jmeno1" && $Nheslo == "heslo1") || ($Njmeno == "jmeno2" && $Nheslo == "heslo2") || ($Njmeno == "jmeno3" && $Nheslo == "heslo3") || ($Njmeno == "jmeno4" && $Nheslo == "heslo4") ) { //ulozim si jmeno uzivatele do session session_start(); $_SESSION['jmeno'] = $Njmeno; $staryobsah = file_get_contents("online.txt"); $soubor = fopen("online.txt", "w"); //zkusim zaktualizovat cas posledni aktivity v souboru, pokud se uzivatel //prihlasuje a je v souboru z minula (napr. neodhlasil se) $zaktualizovano = preg_replace("/".$Njmeno.":\d+;/U", $Njmeno.":".time().";", $staryobsah, 1, $pocet); //pokud pocet zmenenych zaznamu == 0 if($pocet == 0){ //neni v souboru, takze ulozime novy zaznam (jmeno s aktualnim casem) fwrite($soubor, $Njmeno.":".time().";".$staryobsah); fclose($soubor); }else{ //je v souboru, takze jenom ulozime zaktualizovany udaj o case fwrite($soubor, $zaktualizovano); fclose($soubor); } //presmerujeme na chraneny obsah header("Location: stranka.php"); }else{ echo "Špané heslo nebo jméno." } ?> kontrola.php: <?php //vytahneme si jmeno ze session session_start(); $Njmeno = $_SESSION['jmeno']; $staryobsah = file_get_contents("online.txt"); //nacteme udaj o case ze zaznamu, ktery odpovida jmenu uzivatele if(preg_match("/$Njmeno:(\d+);/U", $staryobsah, $matches)){ //cas je v $matches[1] if($matches[1]>time()-60*10){ //pokud je aktivni, zaktualizujeme cas posledni aktivity v zaznamu a ulozime $zaktualizovano = str_replace("$Njmeno:$matches[1];", $Njmeno.":".time().";", $staryobsah); $soubor = fopen("online.txt", "w"); fwrite($soubor, $zaktualizovano); fclose($soubor); }else{ //pokud byl neaktivni dele nez 10 minut, presmerujeme ho na odhlaseni header("Location: odhlasit.php?duvod=neaktivita"); } }else{ //pokud nebyl nalezen zaznam v souboru, stranka odhlasit.php mu sdeli, ze neni prihlasen header("Location: odhlasit.php?duvod=neprihlasen"); } ?> odhlasit.php: <?php //je-li duvodem to, ze neni prihlasen, sdelime to mu to if(isset($_GET["duvod"]) && $_GET["duvod"] == "neprihlasen"){ echo "Nejste přihlášen, prosím přihlaste se."; }else{ //jinak odhlasime session_start(); $Njmeno = $_SESSION['jmeno']; $staryobsah = file_get_contents("online.txt"); //odstranime zaznam $odstraneno = preg_replace("/".$Njmeno.":\d+;/U", "", $staryobsah, 1); $soubor = fopen("online.txt", "w"); fwrite($soubor, $odstraneno); fclose($soubor); //pokud byla duvodem odhlaseni neaktivita, sdelime mu to if(isset($_GET["duvod"]) && $_GET["duvod"] == "neaktivita"){ echo "Byl jste odhlášen z důvodu neaktivity, prosím přihlaste se."; }else{ //jinak se jednalo o normalni odhlaseni echo "Byl jste úspěšně odhlášen."; } } ?> Script kontrola.php vložíš na začátek každé chráněné stránky. Pro regulerní odhlášení slouží odhlasit.php. |
||
Eflyax Profil |
#14 · Zasláno: 13. 3. 2011, 14:21:48 · Upravil/a: Eflyax
Hmm, pěkná práce, funguje to hezky. Co když uživatel se sám neodhlásí a jenom zavře prohlížeč? Zkoušel jsem to a neodhlásilo mě to.
EDIT: Mohl bych třeba použít skript, který by otevřel texťák, načetl si obsah, rozdělil si jméno a čas (přes explode) a vypsal by pak jen jména s určitým časem. Jdu to vyzkoušet. |
||
Seith Profil |
#15 · Zasláno: 13. 3. 2011, 15:33:23
Eflyax:
„Mohl bych třeba použít skript, který by otevřel texťák, načetl si obsah, rozdělil si jméno a čas (přes explode) a vypsal by pak jen jména s určitým časem. Jdu to vyzkoušet.“ Ano, to jsem měl na mysli. |
||
Eflyax Profil |
#16 · Zasláno: 13. 3. 2011, 15:50:09 · Upravil/a: Eflyax
Zkusil jsem ten skript vytvořit a na 80% to funguje jak si představuju, bohužel je tam zase jeden problém.
Použil jsem přihlašování od Seitha - všechno v pořádku. Napsal jsem si skript, který by mi měl vypisovat všechny uživatele, co jsou online (za posledních 10 sekund). Problém mám tenhle: Přihlásí se uživatel1... mezitím se přihlásí uživatel2... oba jsou online, skript funguje. Pokud ale uživatel2 je 10 sekund neaktivní, neměl by ho skript vypsat - on ale nevypíše nikoho. I přes to, že uživatel1 je pořád přihlášený a aktivní, kvůli uživateli2 není jakoby nikdo online. Můj skript vypis.php: <? $soubor = File('online.txt'); foreach ($soubor as $z) { List($Njmeno, $cas) = Explode(':',$z); // <-- podle mě je problém někde tady // v souboru online.txt rozdělí data na jméno a čas... } if(time() - $cas <= 10 ) //...od aktuálního času odečtu čas aktivity uživatele - pokud je to více jak 10 sekund, // je neaktivní a nechci ho vypsat. { $file = fopen("online.txt","r"); $obsah = fread($file,filesize("online.txt")); fclose($file); echo ($obsah); // mělo by to vypsat online uživatele za posledních 10 sekund //(vypíše se jméno uživatele i s jeho časem ale to mi zas tak nevadí) } else echo "Nikdo není online"; ?> Stručně řečeno, výpis aktivních uživatelů závisí na jednom uživateli. Potřebuji aby se to u každého jména ověřilo zvlášť. :-( |
||
Seith Profil |
#17 · Zasláno: 13. 3. 2011, 16:12:49
Zkus tohle:
<?php $obsah = file_get_contents("online.txt"); $zaznamy = explode(";", $obsah); unset($zaznamy[count($zaznamy)-1]); foreach($zaznamy as $zaznam){ $zaznam = explode(":", $zaznam); if ($zaznam[1] > time()-10*60){ echo $zaznam[0]."<br>"; } } ?> |
||
Eflyax Profil |
#18 · Zasláno: 13. 3. 2011, 16:42:46
Jó, to je to, co potřebuju. Teď jsem spokojen na 110% ! Moc moc ti děkuju, opravdu jsi mi pomohl.
|
||
Seith Profil |
#19 · Zasláno: 13. 3. 2011, 16:46:55
Eflyax:
Díky, rád jsem pomohl, můžu vědět co to stavíš? |
||
Eflyax Profil |
#20 · Zasláno: 13. 3. 2011, 17:13:24
Seith:
Řekněme systém (v intranetu), kam se můžou přihlásit lidé a můžou spolu komunikovat i bez internetu. |
||
Časová prodleva: 13 let
|
0