Seuraavanlainen ongelma:
Olen rakentanut kokeilumielessä eräänlaisen elokuvatietokannan. Tietokantaan on tallennettu elokuvan nimi ja arvosteluteksti sille. Tietokannalle on kolme käyttäjätunnusta: administrator, arvostelija ja vieras. Näistä admin voi muokata elokuvatietokannasta niin elokuvan arvostelua kuin nimeäkin, arvostelija voi muokata pelkästään arvostelutekstiä, ja vieras voi ainoastaan lukea arvosteluita.
PHP-systeemi on yksinkertainen.
* Index.php -> kirjautumislomake
* login.php -> tarkistaa kirjautumisen oikeellisuuden tietokannasta.
* main.php -> luo listan (ja linkit) tietokannan elokuviin.
* details.php -> näyttää elokuvan arvostelun, lisää muokkausoptiot adminille ja arvostelijalle.
* logout.php -> uloskirjautuminen
Ongelmani on seuraavanlainen: Systeemi tuntuu muutoin toimivan mukavasti, mutta ainakin Explorerilla uloskirjautuminen ei tunnu täysin toimivan. Jos kirjaudun ensin sisälle adminina, niin myöhemmin vieraana saatankin saada käyttööni oikeudet muokata arvosteluita. Tämä tuntuisi liittyvän jotenkin selaimen välimuistiin? Tuttu ongelma kenellekään?
Auttaisivatko nuo? Laita ne ihan sivun alkuun.
header("Cache-control: private, no-cache");
header("Expires: Mon, 10 Jan 2000 09:00:00 GMT");
header("Pragma: no-cache");
Onnistuuko arvosteluiden muokkaaminen todella vai tuleeko näkyviin vain vanha muokkaussivu? Ensimmäisessä tapauksessa kirjautuminen on jostain syystä jäänyt voimaan, toisessa tapauksessa vanha sivu voi tulla välimuistista. Voit testata asian vaikka tulostamalle sivulle kellonajan. Miten muuten olet toteuttanut kirjautumisen?
@jarih: täytyy kokeilla tuota myöhemmin illalla.
@Antti: tarkoitat ilmeisesti että onnistuuko vieraan tekemä tekstinmuokkaus? Sikäli kun olen pystynyt ongelmaa jäljittämään, niin virhetilanteessa vieras pystyy muokkaamaan ruudulla (lomakkeessa) tekstiä, mutta se ei tallennu (tallentaminen hoidetaan erillisessä .php-sivussa). Tämän ja parin muun ongelman vuoksi (mm. adminin tekemän muokkauksen jälkeen muokkaukset kyllä tallentuvat tiedostoon, mutta eivät ilmesty ruutuun ennenkuin seuraavalla kirjautumisella) epäilen vahvasti selaimen välimuistiongelmaa.
Kirjautuminen on jaettu kahteen php-tiedostoon: index.php ja login.php. Minulla ei ole niitä juuri nyt käytettävissäni (kotikoneen kovalevyllä, ja työkoneelta puuttuu sftp-softa jolla saisin ne haettua). Laitan ne vaikka vielä illemmalla kunhan pääsen kotikoneelle.
Valitan myöhäistä vastausta.. Oma tietokone sattuneesta syystä offline koko illan. Tässä kuitenkin..
* Index.php:
<?php session_start(); // tarkistetaan onko käyttäjällä jo istunto menossa if ($_SESSION["sess_tunnus"] != $_SERVER["REMOTE_ADDR"]) { $tarkastus = "login.php"; echo "<form action=\"". $tarkastus ."\" method=\"post\">\n"; echo "<b>Kirjaudu sisään</b><br>\n"; echo "Tunnus: <input type=\"text\" name=\"tunnus\"><br>\n"; echo "Salasana: <input type=\"password\" name=\"salasana\"><br>\n"; echo "<input type=\"submit\" value=\"Kirjaudu\" name=\"kirjaudu\">\n"; echo "</form>"; } else { // jos on, niin siirrytään suoraan pääsivulle $main_page_url = "main.php"; header("Location: http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/" . $main_page_url); } ?>
* login.php:
<?php session_start(); $heppu = $_POST['tunnus']; $pword = $_POST['salasana']; $yhteys = mysql_connect(); if (! $yhteys) die("Ei tietokantapalvelinta!"); $tietokanta = "pwords"; mysql_select_db($tietokanta) or die("Salasanatietokantaa ei löytynyt!".mysql.error()); $kysely = "SELECT * FROM arvot WHERE nimi='" . $heppu . "'"; $haun_tulos = mysql_query($kysely) or die("virhe kyselyssä!"); if (mysql_num_rows($haun_tulos) < 1) { echo "Tarkista tunnus ja salasana."; echo "<p>"; echo "<a href=\"index.php\">Yritä uudestaan</a>"; mysql_close($yhteys); } else { $salasana = mysql_result($haun_tulos, 0, "arvo"); if (md5($pword) == $salasana) { // tallennetaan istuntomuuttujat $_SESSION["sess_tunnus"] = $_SERVER["REMOTE_ADDR"]; $_SESSION["session_user"] = $heppu; // ohjataan sovelluksen pääsivulle $main_page_url = "main.php"; header("Location: http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/" . $main_page_url); mysql_close($yhteys); } else { echo "Tarkista tunnus ja salasana."; echo "<p>"; echo "<a href=\"index.php\">Yritä uudestaan</a>"; mysql_close($yhteys); } } ?>
Nuo headerit poistivat alkuperäisen ongelman. Ratkaisusta suuri kiitos jarih:lle.
Nyt vielä pieni yhteyden sulkemiseen liittyvä ongelma. Sovelluksessani uloskirjautuminen tapahtuu logout.php -tiedostossa, jonka koodi on seuraava:
<?php header("Cache-control: private, no-cache"); header("Expires: Mon, 10 Jan 2000 09:00:00 GMT"); header("Pragma: no-cache"); session_start(); // poistetaan istuntomuuttujat unset($_SESSION["sess_tunnus"]); unset($_SESSION["session_user"]); // ilmoitus ja linkki kirjautumissivulle echo "Olet nyt kirjautunut ulos.<p>"; echo "<a href=\"index.php\">Palaa Loginiin</a>";
Ongelmani on seuraavanlainen. Vaikka käyttäjä olisi kirjautunut ulos, niin jos samalta koneelta (mahdollisesti muualtakin) avataan suoraan jokin sivuston välisivu (esim. main.php), niin ko. sivua avattaessa jo suljetuksi luultu istunto onkin auki, ja sivun avaaja saa pahimmassa tapauksessa suoraan adminin oikeudet.
Ilmeisesti istunto ei olekaan kunnolla sulkeutunut?
offtopic: Anteeksi, että taas valitan tästä, mutta lukekaa keskustelun ohjeet ja käyttäkää koodi-tagia,
[koodi PHP] [/koodi]
Eikö olisikin mukavampaa, jos tästä ei tarvitsisi huomautella? Kiitos.
Tuohon Juicen kommenttiin jatkaen, myös uudet putkalaiset osaisivat kooditageja käyttää, jos kooditageille olisi buttonit tuossa vieressä. Olen tätä aikaisemminkin ehdottanut ja ehdotan taas. Buttonit tuohon viereen tähän tyyliin. Javascriptittömät älkää vaivautuko.
Niin ja vastataan nyt vielä tuohon alkuperäiseenkin ongelmaan. Cirry koita tuhota sessiokeksi noiden toimenpiteiden lisäksi:
<?php // poistetaan istuntomuuttujat unset($_SESSION["sess_tunnus"]); unset($_SESSION["session_user"]); session_destroy(); setcookie("PHPSEESID","",-1); ?>
Ah, pyydän nöyrimmästi anteeksi noiden kooditagien puuttumista. Luin kyllä ohjeet kun liityin, mutta jotenkin katosi mielestä kokonaan tätä kirjoittaessa (olen välillä sellainen tyhjäpää, että...). Pyrin visusti muistamaan tämän jatkossa.
ajv:lle vielä tarkennus, että tarvitaanko tuota "setcookie"-käskyä, kun koodini pitäisi ilmeisesti toimia puhtailla istunnoilla (ts. ilman evästeitä)? Vai olenko _jälleen_ kerran ymmärtänyt jonkin PHP/session-asian täysin päin honkia?
sessiomuuttujat voi myös tyhjentää käskyllä
$_SESSION = array();
Cirry kirjoitti:
ajv:lle vielä tarkennus, että tarvitaanko tuota "setcookie"-käskyä, kun koodini pitäisi ilmeisesti toimia puhtailla istunnoilla (ts. ilman evästeitä)? Vai olenko _jälleen_ kerran ymmärtänyt jonkin PHP/session-asian täysin päin honkia?
Niin no tietääkseni sessiot toimivat oletuksena kekseillä, mutta jos näin ei ole (sessio kulkee linkeissä ja osoiterivillä(?)), niin sittenhän tuo on turha. Omissa kirjautumisissa kyllä riittää pelkästään tuon sessioarvon unsettaaminen. Yleensähän kirjautumiset toimivat niin, että sessioon tallenetaan vain joku uniikki avain (esim md5($tunnus.$salasana.time()); ) ja sama avain tallennetaan myös kantaan. Sitten jokaisella sivunlatauksella haetaan tuolla avaimella kannasta käyttäjän tiedot. Eli siis ei tallenneta tunnusta ja muita tietoja sessio-muuttujaan.
Ps. setcookie("PHPSEESID","",-1); ==> setcookie("PHPSESSID","",-1); ja tuokin istuntokeksin nimi on vissiin palvelinkohtainen.
ajv: Tuli vielä mieleen, että tuossa esimerkissäsi ei ole ollenkaan alussa session_start()-komentoa. Eikö tätä tarvita? (ihan vain yritän vielä saada vähän selkoa systeemiin, valitan tyhmiä kysymyksiä =P )
Muttamutta.. Lisäsin nuo ehdottamasi rivit tuonne logout.php-sivulle, ja nyt ohjelma tuntuu lopultakin toimivan niin kuin pitääkin. Eli kiitos paljon avusta sinulle ja muillekin!
Ps. ainiin.. omassa koodissani on ainakin vielä tuo session_start() -kutsu ennen niitä sessionpäättämiskoodeja..
Joo, sen session_start():n se tarttee sinne alkuun.
Aihe on jo aika vanha, joten et voi enää vastata siihen.