By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,606 Members | 2,019 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,606 IT Pros & Developers. It's quick & easy.

Logout and Login is Screwy

100+
P: 155
When I logout as one user and log in under a different user, it opens with the last user's information.

User 1 - Unsername: Davey Jones

User 2 - Unsername: David Smith

I log out from Davey Jones, then login as David Smith the Welcome message below will show "Welcome Davey". And it will be Davey's information that is accessible - not David Smith's. So something is amiss but I don't know what.

(BTW, this login script is based on the one found in Larry Ullman's book "PHP and MySQL for dynamic websites 2nd edition - Chapter13.)

Expand|Select|Wrap|Line Numbers
  1. // Welcome the user (by name if they are logged in).
  2. echo '<h1>Welcome';
  3. if (isset($_SESSION['first_name'])) {
  4.     echo ", {$_SESSION['first_name']}!";
  5. }
  6. echo '</h1>';
Here's what I'm trying to do. I use a functions.php page that contains my core website and I call it on every single Web page. For instance on the index.php page it'll have this at the top and bottom of the page:

Expand|Select|Wrap|Line Numbers
  1. At Top of Page
  2. <?php
  3. ob_start();
  4. // Initialize a session.
  5. session_start();
  6. $page_title = "Home";
  7. include('includes/config.inc.php');
  8. include('functions.php');
  9. do_html_header($page_title);
  10. ?>
  11.  
  12. At Bottom of Page
  13. <?php
  14. bottom();
  15. footer();
  16. ?>
  17.  
In between the top and bottom is the content for that page.

The login scripts are located in a folder called "members" - /mysite.com/members/login.php
The pages in the members folder has this at the top of each page:
Expand|Select|Wrap|Line Numbers
  1. At Top of Page
  2. <?php 
  3. include('./../includes/sess.php');
  4. include('./../includes/config.inc.php');
  5. include('js_functions.php');
  6. $page_title = 'Member Control Panel';
  7. include('./../includes/top.php');
  8. login_check();
  9. main_bar();
  10.  
The exception here would the index.php, register and login.php pages which would have real_login_check() function instead of the login_check() and main_bar() functions.

The sess.php contains:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. // This page begins the HTML header for the site.
  3. // Start output buffering.
  4. ob_start();
  5. // Initialize a session.
  6. session_start();
  7. ?>
The top.php contains:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. include("./../functions.php");
  3. do_html_header($page_title);
  4. echo "<h3>$page_title</h3><br>";
  5. ?>
These php pages are located in a folder called "includes" under the root directory - /mysite.com/members/includes/sess.php
The js_function.php page is located in the members folder.

The js_functions.php contains:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2.  
  3. function welcome_bar()
  4. {
  5. echo "
  6. <center>
  7. <div style='width:95%; background-color:#EAF4FF; padding:3px'>
  8. <strong>Welcome!</strong>
  9. </div>
  10. </center>
  11. <br><br>
  12. ";
  13. }
  14.  
  15.  
  16.  
  17. function pages_bar()
  18. {
  19. echo "
  20. <center>
  21. <div style='width:95%; background-color:#EAF4FF; padding:3px'>
  22. Return to <a href='main.php'><u><strong>Member Control Panel</strong></u></a>
  23. </div>
  24. </center>
  25. <br><br>
  26. ";
  27. }
  28.  
  29.  
  30.  
  31. function main_bar()
  32. {
  33. echo "
  34. <center>
  35. <div style='width:95%; background-color:#EAF4FF; padding:3px'>
  36. <strong>What would you like to do?</strong>
  37. </div>
  38. </center>
  39. <br><br>
  40. ";
  41. }
  42.  
  43.  
  44.  
  45. function login_check()
  46. {
  47. // If no user_id variable exists, redirect the user.
  48. if (!isset($_SESSION['user_id']))
  49. {
  50.  
  51. // Start defining the URL.
  52. $url = 'http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']);
  53.  
  54. // Check for a trailing slash.
  55. if ((substr($url, -1) =='/') OR (substr($url, -1) == '\\') )
  56. {
  57.  
  58. // Chop off the slash.
  59. $url = substr ($url, 0, -1);
  60. }
  61.  
  62. // Redirect to this page if not logged in.
  63. $url .= './../members/login.php';
  64. header("Location: $url");
  65.  
  66. // Quit the script.
  67. exit();
  68.  
  69. }
  70. else
  71. {
  72. // Welcome the user (by name if they are logged in).
  73.  
  74. if (isset($_SESSION['user_title']) && ($_SESSION['first_name']) && ($_SESSION['last_name']));
  75. {
  76. echo "
  77. <p><strong>Hello:</strong> {$_SESSION['user_title']} {$_SESSION['first_name']} {$_SESSION['last_name']}</p>
  78. ";
  79. }
  80. }
  81. }
  82.  
  83.  
  84.  
  85. function real_login_check()
  86. {
  87. // If user_id variable exists, redirect the user.
  88. if (isset($_SESSION['user_id']))
  89. {
  90.  
  91. // Start defining the URL.
  92. $url = 'http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']);
  93.  
  94. // Check for a trailing slash.
  95. if ((substr($url, -1) =='/') OR (substr($url, -1) == '\\') )
  96. {
  97.  
  98. // Chop off the slash.
  99. $url = substr ($url, 0, -1);
  100. }
  101.  
  102. // Redirect to this page if not logged in.
  103. $url .= './../members/main.php';
  104. header("Location: $url");
  105.  
  106. // Quit the script.
  107. exit();
  108. }
  109. else
  110. {
  111. echo "
  112. <center>
  113. <div style='width:95%; background-color:#EAF4FF; padding:3px'>
  114. <strong>Welcome!</strong>
  115. </div>
  116. </center>
  117. <br><br>
  118. ";
  119. }
  120. }
  121. ?>
The index.php, register.php and login.php pages in the members folder are the only pages that uses the real_login_check(); function. If the user is logged in they will be directed to the main.php page which contains the information pertinent to them. If the person isn't logged in the login form will be displayed or the registration form in the case of register.php.

I tried to get cute and place a login form at the top of the functions.php page to eliminate the need to first go to the member's area to log in. If the user is logged in the welcome message is displayed instead of the login form. Here is that bit of code:

Expand|Select|Wrap|Line Numbers
  1. if (isset($_SESSION['user_id']) AND (substr($_SERVER['PHP_SELF'], -10) != 'members/logout.php'))
  2. {
  3. echo "
  4. <strong>Hello, {$_SESSION['user_title']} {$_SESSION['first_name']} {$_SESSION['last_name']}</strong><br />
  5. <a href='http://www.mysite.com/members/logout.php'>Logout</a><br />
  6. <a href='http://www.mysite.com/members/index.php'>Member Control Panel</a>
  7. ";
  8. }
  9. else
  10. {
  11. // Not logged in
  12. echo "
  13. <form action='http://www.mysite.com/members/login.php' method='post'>
  14. <strong>Member Login:</strong><br />
  15. Email Address <input type='text' name='email' size='15' maxlength='45' value=''><br />
  16. Password <input type='password' name='pass' size='10' maxlength='20'><br />
  17. <input type='submit' name='submit' value='Login'>
  18. <input type='hidden' name='submitted' value='TRUE'>
  19. </form>
  20. <br />
  21. <a href='http://www.mysite.com/members/register.php'>Register</a>
  22. ";
  23. }
I want to enable sessions for many of the pages in the root directory, so I have this at the top of each page:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. ob_start();
  3. // Initialize a session.
  4. session_start();
In the functions.php page I have the footer() function that contains this:
Expand|Select|Wrap|Line Numbers
  1. </body></html>";
  2. ob_end_flush();
Since the pages in the members folder also calls the functions.php page they too have the ob_end_flush() function.

So, back to my problem of the last user "logged out" being carried over when someone else logs in. I'm not sure where the problem lies. I think I have listed everything here in this post that relates to logging in and sessions. These are the variables that are set when logging in:
Expand|Select|Wrap|Line Numbers
  1. // Register the values & redirect.
  2. $row = mysql_fetch_array ($result, MYSQL_NUM);
  3. mysql_free_result($result);
  4. mysql_close(); // Close the database connection.
  5.  
  6. $_SESSION['user_id'] = $row[0];
  7. $_SESSION['email'] = $row[1];
  8. $_SESSION['user_title'] = $row[3];
  9. $_SESSION['first_name'] = $row[4];
  10. $_SESSION['last_name'] = $row[5];
  11. $_SESSION['city'] = $row[7];
  12. $_SESSION['stateid'] = $row[8];
I really don't understand the -10 in the code found in the functions.php page:
Expand|Select|Wrap|Line Numbers
  1. (substr($_SERVER['PHP_SELF'], -10) != 'members/logout.php')
Does the -10 set the logging out for 10 minutes in the past to make logging out instantaneous?

I would like to keep the logging in feature at the top of all the pages. It's much like the one on this website and I find it quite handy. But if this is what is causing my logout and login problems, and if it can't be fixed I'll scrap it.

Thanks for any help.
David
Dec 4 '08 #1
Share this Question
Share on Google+
10 Replies


P: 65
What is the code of your footer.php script? I don't think I see it in that massive post of yours. That's probably where your problem is occurring. It should be either destroying the session entirely, or setting all the values of PHP's superglobal $_SESSION to NULL to completely wipe the trace of the active login from the session. So if logging out only unsets one thing (the user_id) it may fool the script that the user is logged out, but the $_SESSION variable still contains all the variables.

Maybe in your logout script add a:
Expand|Select|Wrap|Line Numbers
  1. foreach ($_SESSION as $key => $value) {$_SESSION [$key] = NULL;}
  2. session_destroy ();
  3. session_start ();
If the above code is already present, posting your logout.php script would help.

Also, someone made a comment at the PHP website that seems to provide a solution to what's wrong with your script since you stated your login and logout scrips are located in a sub directory.
A session created with session_start will only be available to pages within the directory tree of the page that first created it.
Dec 5 '08 #2

100+
P: 155
Massive yes, and my fingers still hurt from typing it. I didn't know how else to explain what I was trying to do and how I was trying to do it.

I have this in the logout.php page:
Expand|Select|Wrap|Line Numbers
  1. $_SESSION = array(); // Destroy the variables.
  2. session_destroy(); // Destroy the session itself.
  3. setcookie (session_name(), '', time()-300, '/', '', 0); // Destroy the cookie.
That's very interesting about the session having to remain in the directory in which it was created. Larry made no mention of this in his book. It's not sounding too good for my login script on top of all the pages.

If a session is created in the members sub-directory, and I don't have session_start() on root directory pages (because the session isn't any good there anyway since it wasn't started there), and the user leaves the members sub-directory to view pages in root and other folders, and then goes back to the members sub-directory - will their session information still be intact or will they have to log back in again?
Dec 5 '08 #3

P: 65
I believe that if they start their session inside of the members subdirectory, their session will not persist outside of the members subdirectory.

You mentioned a login box on the funtions.php file so they do not have to go to the members control panel; if this doesn't forward you to a file in members on the form submission, you may have two different sessions going. And when you logout in the members panel, you may be destroying that specific session, and not the one outside of it.

I'm not too sure really. I've found that the PHP session handler is just not for my tastes. It has many quirks and other stuff; it can also "collide" with other applications on your website, even other people's websites (if you're on a shared hosting solution that has a poor setup). I, personally have always had problems with the PHP session handler's way of creating and destroying sessions that I tend to try to steer clear of it in favor of one that is controlled by a custom session handler script linked to a database.

I will look through the code a little better on this second pass to try to further "diagnose" the problem. :)

While you're waiting though, I suggest you try the one solution I can think of (if that comment is a good reason as to why it's not working). Try moving everything of the members directory out into the root folder.
Dec 5 '08 #4

P: 65
I've had a slight spark of genious of my old days of using the PHP session handler...

It looks like it's not being fully killed (typical)

If logout.php doesn't stop the session entirely; kill the old one, and leave it by starting a new one with a different identifier entirely.

Try this in logout.php:
Expand|Select|Wrap|Line Numbers
  1. $_SESSION = array(); // Destroy the variables.
  2. session_unset (); // Destroy the variables?! (It's the remedy of popping every single pill)
  3. session_destroy(); // Destroy the session itself.
  4. session_start (); // Re-start the session.
  5. session_regenerate_id (); // Ensure that we get this visitor a new session identifier.
  6. $_SESSION = array(); // Destroy the variables (again).
Dec 5 '08 #5

100+
P: 155
I may do that (move everything out of the members directory).

Right now, the login/logout form on the funtions.php page is linked to the main login.php form in the members directory where the actual logging in and the setting of the session takes place. Same thing for the logout link in the functions.php page:
Expand|Select|Wrap|Line Numbers
  1. <a href='members/logout.php.'>Logout</a>

custom session handler script linked to a database
Sounds interesting.
Dec 5 '08 #6

P: 65
Yup, I posted a snapshot of my session handler here in fact (I didn't test it, I just finished writing the 800 or so lines of code, it didn't even work in that state, just produced an error, then a fatal error). My code was deleted because I broke the posting guidelines. :)

The current state is 7,900 lines (including the support classes it relies on), and works flawlessly.

You can probably find a much smaller one that conforms to your needs specifically somewhere on Google. Try that little code replacement I gave you for logout.php first, and see if all goes well.
Dec 5 '08 #7

100+
P: 155
I tried it but it still kept loggin me in as the same guy. I've just deleted all references to session outside of the members folder. I'll check that and see if it still logs me in as the same guy now. If so, then it has to have something to do with my version of PHP5+, as I running this exact login feature on other websites just fine. Those websites are on a server that uses a lower version of PHP. Or at least how my hosting company has the php.ini file setup.
Dec 5 '08 #8

100+
P: 155
No, it's definately a compatibility issue with the version of PHP my server is running and this login script from Larry Ullman's book. It's the same login mechanism that's running fine on other websites but not this one, only thing different is the server.
Dec 5 '08 #9

pbmods
Expert 5K+
P: 5,821
@DavidPr
The -10 means to start 10 characters from the *end* of the string (PHP: substr - Manual).

Literally, that statement means, "If the last 10 characters of $_SERVER['PHP_SELF'] are not 'members/logout.php'...".

This statement will always evaluate to true because 'members/logout.php' is 18 characters, not 10.

A better conditional would probably be:
Expand|Select|Wrap|Line Numbers
  1. if( ! preg_match('|members/logout\\.php$|', $_SERVER['REQUEST_URI']) )
  2.  
$_SERVER['REQUEST_URI'] only looks at the URI of the request and ignores querystring variables.
Dec 6 '08 #10

Motoma
Expert 2.5K+
P: 3,235
Hi DavidPr,

If you are still having difficulty with these, I would suggest checking two things: your logout handling, as well as the order that login and the welcome message are rendered.

In my mind, the safest way to handle the a system logout is to clear your user and session data, destroy any open classes, and generate a new session id. A simplified example of this would be:

Expand|Select|Wrap|Line Numbers
  1. <?php
  2. // logout.php
  3.  
  4. session_start();
  5. session_unset();
  6. $application->close();
  7. session_regenerate_id();
  8. header("Location: /");
  9.  
  10. ?>
  11.  
This will ensure that your data is gone, and that any new session will have a new ID (staving of the potential for an old user to snoop the next user's data).

A simple reason why the old user's name is being presented may be because you are calling setting the users' session variables after calling the welcome message code; that is to say you may be calling login_check before you are querying your database.

An easy way to test this would be to put some simple debug echos in your code; for debugging purposes I usually put make each function echo it's name immediately when called to ensure my call order is correct.

Hope this helps,
Motoma
Dec 6 '08 #11

Post your reply

Sign in to post your reply or Sign up for a free account.