Προς το περιεχόμενο

PHP & sessions


j210868k

Προτεινόμενες αναρτήσεις

Εχω φτιάξει ενα συστημα login. Δουλέυει σωστά. Οταν ο χρήστης βάλει τα σωστά δεδομένα username,pass τότε η ροή του προγράμματος πηγαίνει στο ακόλουθο σημείο.

session_start();

$_SESSION['login'] = 1;

header("location:Page1.htm");

Οταν κάνω logout έχω τον πρακάτω κώδικα.

session_start();

session_destroy();

header("location:http://127.0.0.1/Logout.html");

Μέχρι εδώ όλα καλά.

Το προβλημά μου είναι το παρακάτω. Κάνω logout. Γυρίζω τον browser μία ή δύο σελίδες πίσω με το βέλος (μετάβαση μια σελίδα πίσω) βλέπω τις προηγούμενες σελίδες και μπορώ να δουλέψω κανονικά ενώ δεν θα έπρεπε. Αυτό που θα περίμενα είναι με το πρώτο click σε κάποιο link να με ξαναέβγαζε στην φόρμα login. Δηλ. απλά δεν δουλέυουν τα sessions.

Επιπλέον ξέρει κάποιος πως μπορώ να καταστρέψω ένα πλευρικό πράθυρο στον browser με php;

Εχει κανείς καμία ίδεά;;;;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

http://php.net/manual/en/function.session-destroy.php

http://www.phpf1.com/tutorial/php-sessions.html

δεν είμαι και πολύ σχετικός! :mrgreen:

μάλλον πρέπει σε κάθε σελίδα-βήμα του "προγράμματός" σου,

να γίνεται κάποιος έλεγχος και να προχωράει στο επόμενο βήμα ή

να πηγαίνει σε μιά σελίδα που θα ζητάει login

 

.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

ο κώδικας είναι ελλιπής... Πόσταρε από την αρχή το πως λειτουργεί για να δούμε πως δουλεύει. Τα sessions δουλεύουν,εσύ έχεις κάποιο λάθος...

Επίσης όταν σταματάς να χρησιμοποιείς τις μεταβλητές της συνεδρίας πρέπει οπωσδήποτε να την κλείνεις!

>
.
.
.
$_SESSION['login'] = 1;
// $_SESSION can still be read, but writing will not update the session.
// the lock is removed and other scripts can now read the session
session_write_close();
.
.
.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καταρχήν σας ευχαριστώ πολύ.

Ελεγχος................................

<?PHP

 

$user=$_POST['Username'];

$pass=$_POST['Password'];

 

if (!isset($user) || !isset($pass))

{

header( "Location:login.php");

}

 

if ( ($user=="admin")&& (md5($pass)=="c5d7fa6ad2e5490b72dfff23b3e700e1") )

{

session_start();

$_SESSION['login'] = 1;

header("location:index.htm");

}

else

echo "Wrong username and password";

?>

 

Απο εδώ και πέρα σε κάθε φόρμα πριν απο το <html> βάζω

 

<?PHP

session_start();

if (isset($_SESSION['login']) && ($_SESSION['login'] != 1) )

header("location:http://127.0.0.1:8888/Net%20T/index.html");

?>

 

Οταν θέλω να κάνω logout γράφω

 

<?PHP

session_start();

session_unset();

session_destroy();

?>

δυστηχώς δεν δουλεύει.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

θα σου πρότεινα να κάνει το εξής. Να φτιάξεις ένα αρχείο php και να βάλεις μέσα συναρτήσεις όπως την "login" & "logout" ώστε να μη χρειάζεται να γράφεις τα ίδια και τα ίδια και θα το κάνεις include με την require_once('mysessfuncs.php')

Επίσης στον κώδικά σου πρέπει να βάζεις απαραίτητα το session_write_close();

πχ το αρχείο mysessfuncs.php:

>
<?php
function user_logout()
{
	session_start();
	session_unset();
	session_destroy();
}

function user_login()
{
	session_start();
	$_SESSION['login'] = 1;
	session_write_close();
}

function is_session()
{
	session_start();
	$ival = isset($_SESSION['login']) && ($_SESSION['login'] != 1);//ΑΥΤΟ ΤΟ ΚΟΜΜΑΤΙ ΚΑΝΕΙ ΤΗ ΣΥΓΚΡΙΣΗ ΚΑΙ ΝΑ ΠΕΡΝΑΕΙ ΤΗΝ ΤΙΜΗ ΣΤΗΝ $ival
	session_write_close();
	
	return $ival;
}
?>

και ο δικός σου κώδικας τροποποιημένος:

>
<?PHP
require_once('mysessfuncs.php');

$user=$_POST['Username'];
$pass=$_POST['Password'];

if (!isset($user) || !isset($pass))
{
header( "Location:login.php");
}

if ( ($user=="admin")&& (md5($pass)=="c5d7fa6ad2e5490b72dfff23b3e700e1") )
{
user_login();
header("location:index.htm");
}
else
echo "Wrong username and password";
?>

Απο εδώ και πέρα σε κάθε φόρμα πριν απο το <html> βάζω

<?PHP
require_once('mysessfuncs.php');
if ( is_session() )
{
    header("location:http://127.0.0.1:8888/Net%20T/index.html");
}
?>

Οταν θέλω να κάνω logout γράφω

<?PHP
require_once('mysessfuncs.php');
user_logout();
?>

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το πρόβλημά σου είναι ότι ο browser κρατάει τις σελίδες στο ιστορικό του, γι' αυτό και στιςεμφανίζει ενώ δε θα έπρεπε. Δοκίμασε να βάλεις στην κορυφή της σελίδας που προστατεύεις συτές τις γραμμές:

><?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>

έτσι ώστε να αναγκάζεις τον browser να την ξανακατεβάσει

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

θα σου πρότεινα να κάνει το εξής. Να φτιάξεις ένα αρχείο php και να βάλεις μέσα συναρτήσεις όπως την "login" & "logout" ώστε να μη χρειάζεται να γράφεις τα ίδια και τα ίδια και θα το κάνεις include με την require_once('mysessfuncs.php')

Επίσης στον κώδικά σου πρέπει να βάζεις απαραίτητα το session_write_close();

πχ το αρχείο mysessfuncs.php:

>
<?php
function user_logout()
{
	session_start();
	session_unset();
	session_destroy();
}

function user_login()
{
	session_start();
	$_SESSION['login'] = 1;
	session_write_close();
}

function is_session()
{
	session_start();
	$ival = isset($_SESSION['login']) && ($_SESSION['login'] != 1);//ΑΥΤΟ ΤΟ ΚΟΜΜΑΤΙ ΚΑΝΕΙ ΤΗ ΣΥΓΚΡΙΣΗ ΚΑΙ ΝΑ ΠΕΡΝΑΕΙ ΤΗΝ ΤΙΜΗ ΣΤΗΝ $ival
	session_write_close();
	
	return $ival;
}
?>

και ο δικός σου κώδικας τροποποιημένος:

>
<?PHP
require_once('mysessfuncs.php');

$user=$_POST['Username'];
$pass=$_POST['Password'];

if (!isset($user) || !isset($pass))
{
header( "Location:login.php");
}

if ( ($user=="admin")&& (md5($pass)=="c5d7fa6ad2e5490b72dfff23b3e700e1") )
{
user_login();
header("location:index.htm");
}
else
echo "Wrong username and password";
?>

Απο εδώ και πέρα σε κάθε φόρμα πριν απο το <html> βάζω

<?PHP
require_once('mysessfuncs.php');
if ( is_session() )
{
	header("location:http://127.0.0.1:8888/Net%20T/index.html");
}
?>

Οταν θέλω να κάνω logout γράφω

<?PHP
require_once('mysessfuncs.php');
user_logout();
?>

 

Είναι bad practice να ανοιγοκλείνεις το session σε κάθε αλλαγή που κάνεις. Το ανοίγεις μια φορά, πάνω πάνω στο script και το κλείνεις μια, πριν κλείσεις το script (είτε στο τέλος του, είτε πριν φύγεις με χρήση header/location, είτε όταν δουλεύεις με framesets). Περισσότερα εδώ.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Είναι bad practice να ανοιγοκλείνεις το session σε κάθε αλλαγή που κάνεις. Το ανοίγεις μια φορά, πάνω πάνω στο script και το κλείνεις μια, πριν κλείσεις το script (είτε στο τέλος του, είτε πριν φύγεις με χρήση header/location, είτε όταν δουλεύεις με framesets). Περισσότερα εδώ.

Που λέει ότι είναι bad practice και γιατί; Ο τρόπος που πόσταρα είναι πολύ τακτοποιημένος γιατί αν ξεχάσεις να δώσεις το session_write_close() τα πράγματα θα γίνουν λίγο χάλια στο session. Ειδικά όταν προσπαθήσεις να το ξανανοίξεις (session_start) χωρίς να έχεις δώσει πριν session_write_close().

session_write_close() worked as a lifesaver for me when automatically uploading files to a user (forcing a download instead of a link). If files are large, and since session_start() does not allow another page using session_start() to proceed until it's done, i was not able to upload more than one file at a time. By using session_write_close() before beginning the file upload, my users can now download as many big files as they like, at the same time. Example:

 

<?

session_start();

/* Do session stuff here; security; logging; etc. */

session_write_close();

/* NOW write out the requested file. */

header("Content-type: audio/x-mpeg"); /* or whatever type */

header("Content-Disposition: attachment; filename=" . $filename);

header("Content-Length: " . $filesize);

header("Content-Transfer-Encoding: binary\n\n");

header("Pragma: no-cache");

header("Expires: 0");

$file_contents = file_get_contents($filepath);

print($file_contents);

?>

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Η php πάντα τερματίζει το session από μόνη της όταν αλλάζεις script. Τί εννοείς ακριβώς ότι θα γίνουν χάλια τα πράγματα στο session;

 

Το quote σου αφορά μια συγκεκριμένη περίπτωση που ο χρήστης είχε upload μεγάλων αρχείων. Επίσης, αυτό που έχεις κάνει bold λέει ουσιαστικά, ότι αν ανοίξεις μια φορά το session, δεν μπορείς να φορτώσεις κάποιο άλλο script που ανοίγει το session (το οποίο είναι λογικότατο, δεν μπορείς να έχεις δυο ενεργά sessions). Γι αυτό πρέπει να ανοίγει μόνο μια φορά πάνω πάνω και να κλείνει επίσης μια, κάτω κάτω (αν και δεν είναι απαραίτητο να το κλείσεις). Το λοκάρισμα του session πρέπει να γίνεται μόνο αν συντρέχει συγκεκριμένος λόγος (πχ θέλεις να κάνεις include κάποιο script που παίρνει παραμέτρους από το ενεργό script, αλλά δεν θέλεις να μπορεί να τις αλλάξει).

 

Bad practice είναι γιατί φορτώνεις με κώδικα το script χωρίς να συντρέχει λόγος. Όπως είναι bad practice να χρησιμοποιείς if-else statement για ανάθεση μεταβλητής (βλ. ternary operator). Φαντάσου ένα project 7-8 χιλιάδων γραμμών php να ανοιγοκλείνει το session κάθε φορά που θέλει write access σε κάποια session μεταβλητή. Θα είχε 20% περισσότερο κώδικα. Bad practice δεν σημαίνει απαραίτητα ότι είναι λάθος ή τσαπατσούλικο. wink.gif

 

ΥΓ> Φιλικά ε, ανταλλαγή γνώσεων/απόψεων κάνουμε. happy.gif

 

EDIT:

 

Ενδιαφέροντα links:

http://shiflett.org/...ssion-debugging

http://phpnightly.co..._write_close-3/

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

το λέω από την εμπειρία μου για μια σελίδα που έφτιαχνα... αλλά ίσως έφταιγε η δομή του κώδικά μου τώρα δε θυμάμαι, αν και τι, είχε συμβεί αν άφηνα ανοιχτό το session πάντως θυμάμαι (με βάση τη δομή) ότι αν τυχόν ήθελα να κάνω session_start και πριν είχα τρέξει μια σελίδα που είχε session_start τότε δεν γινόταν... Αυτό γίνεται στην περίπτωση που υπάρχουν 2 διαφορετικές σελίδες και ο χρήστης δεν ξέρεις αν είχε επισκεφτεί εκείνη που δόθηκε το session_start.

Only one script can access a session at a time. So if you have multiple frames using the same session, one can work while the others wait for the session to be unlocked.

 

In this situation, a call to session_write_close() when you’re done manipulating the session data in a script will free the session to be used sooner by the other script calls. The end result is the frameset being more efficient and loading quicker for the end user.

Αλλά όπως λένε και οι σελίδες που ανέφερες, το session_write_close χρησιμοποιείται για να υπάρχει προστασία των μεταβλητών της συνεδρίας. Επίσης αυτό που είπες ότι να ανοίγει η συνεδρία στην αρχή και να τελειώνει κάτω-κάτω, τι θα γίνει αν υπάρχει redirection κάπου ανάμεσα; Όπως λένε τα παραδείγματα πρέπει να χρησιμοποιείται το session_write_close για να είναι σίγουρο ότι τα δεδομένα έχουν καταγραφεί επιτυχώς

If you are redirecting the user, call this function beforehand. This will ensure that all the data manipulation you did with the $_SESSION array is recorded and available on future calls. I like to put it just before header() so it’s easy to see later on.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μα δεν λέω ότι δεν πρέπει να χρησιμοποιείται η session_write_close, λέω ότι είναι bad practice να χρησιμοποιείται μετά από κάθε write στο session. Προφανώς και για να υπάρχει, έχει χρησιμότητα σαν συνάρτηση...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...