Hello. As you can tell, this is my first post on this forum. Let me assure you that I've searched for solutions on this problem already. I still haven't found a working solution. This is probably the biggest PHP headache I've had so far. And, it's the first time I've ever needed some serious help. Now, on to the problem...

I have a login/logout script that I wrote for a website I am developing. It has all of the headers to disable cache. It uses session unset, destroy, etc. to remove a session when the user clicks the logout button. However, when they click the back button, they are taken to a page that says that "this page has expired". If you refresh, the browser asks if you would like to resend the information. I click yes, and my session is created again, and the username and password are validated.

My first thought was to set $loggedIn to false if no session is found. This skips all of the secure information and display the page with a prompt for a username and password.

I thought I had solved my problems, but woe is me. Now, if you click back you get an expired page. Refresh once and there are no problems. Refresh again and you the username and password authenticates.

I've tried various solutions. I've created a cookie for the session. I've tried creating a file. What I've realized is that all methods produce the same result.

The best solutions I can come up with right now is to save the session ID to the database. If the session ID is equal to the username in my session, do not allow a login. This works for me, but produces a different problem. If I limit one login per session ID, the user can logout, but they cannot login again unless they open a new window, creating a new session ID. If i register a new session ID when the user logs out, the "click back and refresh" hack will work again.

So, are my users doomed to only being allowed to login once per window?

    how do you destroy the session?

      With this:

      $_SESSION = array();
      session_unset();
      session_destroy();

        here is the code to try:

        
        $_SESSION = array();
        $c = session_get_cookie_params();
        $t = gmmktime(0, 0, 0, 1, 1, 1990);
        
        setcookie(session_name(), '', $t, $c['path'], $c['domain'], $c['secure']);
        unset($_COOKIE[session_name()]);
        session_destroy();
        
        exit;
        
        

          That produces the same result. My problem is not that I cannot destroy the session. It's that even though a page has expired....you can still click the refresh button, which asks if you want to resend data. Clicking yes will resend that data, and you are logged in again. The browser remembers values it posts on expired pages.

            do you have a http trace program that can capture http traffic? when you refresh the page that is expired (which is just for pages that have forms submitted through POST requests), can you verify that it sends the SID cookie (I assume that you use session cookies and not SID in the url)? basically, i do not know the answer but i am curious to find out what is causing this. also, another thing to try is to make sure that the session file is deleted before you hit refresh in the browser and see if this makes the problem disappear.

              also, how do you check if the session is logged in?

                Ok. I messed with a bunch of variations of the code you provided. It seems the problem was that I wasnt using the header location properly. This is your script slightly modified:

                $_SESSION = array(); 
                $c = session_get_cookie_params(); 
                $t = gmmktime(0, 0, 0, 1, 1, 1990); 
                
                setcookie(session_name(), '', $t, $c['path'], $c['domain'], $c['secure']); 
                unset($_COOKIE[session_name()]); 
                session_destroy(); 
                
                $newLocation = "location: ".$PHP_SELF;
                header($newLocation);
                

                I'm not exactly sure why this works. But as far as I can tell, it is working now. I am so relieved, I'm half not believing that this works. Thank you for taking the time to answer my question.

                Can you shed a little light to why using the header("location: myfile.php") works?

                  this header sends a 302 http response to the client. do you have a http capture program? i think that 302 responses send the cookie expiration headers and the 200 ok responses do not. but i would like to verify this.

                  before you decided to use redirects, what were your page doing after destroying the session?

                    No, I do not have a capture program.

                    Before I was setting a variable to false, which was meant to prevent certain parts of the page not to display.

                      you can use ipinterceptor if you are on windows.

                      i do not understand regarding a variable. you either were destroying the session or setting a variable in it to indicate that the user has logged out. but not both. i am confused. are you sure your legin verification code is correct?

                        what i was doing is having the code set a variable to false, that prevented certain segmants of the page not to be included.

                        Something like this: if( $myVar ) { include("myPage.php"); }

                        If you want to test my page the link is www.advancedphotofinish.com
                        A temporary username and password you can use is ( un123 - pw123 ). None of the site really works other than logging in and out, and the news.

                          i myself do not have trace software. i cannot help you further.

                            That's ok. It all works now. Thank you for helping. I think you idea is what caused me to realize my mistake.

                              Maybe I'm retarded, but I just noticed that the script isnt fullproof. It doesnt work in Mozilla at all. And every once in a while, it doesnt work in IE. Is there a certain method to this logout madness? It seems like no matter what I do, I can always go back and refresh the page that send the username and password.

                              I've stripped my code way down, taking out the constraints. It doesnt work, but maybe from looking at it, someone can figure out my flaws.

                              <?php
                              	//logging out?
                              	if( $HTTP_POST_VARS['logOut'] ){
                              		//KILL the blasted session and all that it stands for!
                              		//AHHHH DIE SESSION! DIE!!!!
                              		$_SESSION = array(); 
                              		$c = session_get_cookie_params(); 
                              		$t = gmmktime(0, 0, 0, 1, 1, 1990); 
                              
                              	setcookie(session_name(), '', $t, $c['path'], $c['domain'], $c['secure']); 
                              	unset($_COOKIE[session_name()]); 
                              	session_destroy();
                              
                              	$newLocation = "location: ".$PHP_SELF;
                              	header($newLocation);
                              }else{		
                              	//get un/pw
                              	$un = @ $HTTP_POST_VARS['un'];
                              	$pw = @ $HTTP_POST_VARS['pw'];
                              
                              	//if logged into session, continue session
                              	if( isset($_SESSION['un']) && isset($_SESSION['pw']) ){
                              		$un = $_SESSION['un'];
                              		$pw = $_SESSION['pw'];
                              	}
                              
                              	if( isset($un) && isset($pw) ){		
                              		//connect to db
                              		$db = mysql_connect("localhost", "XXXX","XXXX");
                              		mysql_select_db("XXX",$db);
                              
                              		$result = mysql_query("SELECT un FROM XXXX WHERE un='$un' AND pw='$pw'",$db);
                              
                              		//get result
                              		if($myrow = mysql_fetch_array($result)){
                              			//add to session
                              			$_SESSION['un'] = $un;
                              			$_SESSION['pw'] = $pw;
                              
                              			$loggedIn = true;
                              		}else{
                              			$pwFail = true; //will produce an error message
                              			$loggedIn = false;
                              		}
                              
                              		//close db
                              		mysql_close($db);
                              	}
                              }
                              ?>

                                wait, perhaps your original question was not clear to me. you are not talking about re-submitting ANY page (form) in your application from the browser's history, but you are referring to just the LOGIN page submission? you are saying that if the user re-submits the LOGIN page from the browser's history then it logs in without asking to enter user name and password? is this the case?

                                  Yup. Sorry if I wasnt too clear.

                                    what does your login page's html look like? do you use type='password' on your password's <input> tag?

                                      <form method="post" action="" style="margin:0px;" id="loginForm">
                                      <p>
                                      <label for="un">
                                      	<img src="images/icon_un.gif" style="margin-left:12px;" alt="username" />
                                      </label>
                                      <input type="text" name="un" id="un" class="formBox"
                                      style="width:150px;" maxlength="12" /></p>
                                      
                                      <p>
                                      <label for="pw">
                                      	<img src="images/icon_pw.gif" style="margin-left:12px;" alt="password" />
                                      </label>
                                      <input type="password" name="pw" id="pw" class="formBox" 
                                      maxlength="12" style="width:150px;" /></p>
                                      
                                      
                                      <p style="text-align:right;">
                                      	<a href="javascript:document.getElementById('loginForm').submit();">
                                      	<img src="images/submit.gif" style="margin:12px;border:0px;" alt="submit" /></a></p>
                                      </form>

                                        so, basically, if the browser decides to keep your form in memory and let the user resubmit it, you cannot prevent it on the server side. you cannot distinguish real form submissions and the ones done from the history.

                                        but i think there is a way to make the browser not put the form in to its history. i am looking at gmail.com which has a login form. and once you log in and then log out, going back in browser's history does not let me resubmit the form. i think they did it using a client side java script.

                                          Write a Reply...