Link to home
Start Free TrialLog in
Avatar of cracky
cracky

asked on

Sessions Time Out

Hello.

I have written an app that makes use of $_SESSION superglobals to keep user id information intact from page to page within an admin console.

Everything works fine except that the session seems to time out after about 30 mins of inactivity on the site, requiring that the user log in again to continue.

For what it's worth, the admin console is kept in a directory 1-down from the root E.G: /admin/ yet the PHPSESSID cookie says it's from the / path. Could this be messing with the continuity somehow? The cookie is set to expire at the end of session, which is exactly what I want, but obvoiusly it seems to expire earlier.

Anyone got any ideas?
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

I don't believe the path should cause any problems. Sessions are supposed to be able to be passed along seamlessly as long as you stay within the site. Following a link to a different sub-domain or domain will probably kill your session, but that doesn't sound like that's the problem.

I would check your php.ini file and look for your session configuration vars. You can get a table listing of them and also a description of what they do at:

http://www.php.net/manual/en/ref.session.php

If you don't have read access to the php.ini file, you can always just run the function:
<?
phpinfo();
?>

and then search for "auto_start" on that page - that should bring you to the right section. I have a feeling you're going to want to change session.gc_maxlifetime. You should time the process and see if it times out after 24 minutes and a few seconds. If so, try pushing up the gc_maxlifetime to 14400 - that'll give you 4 hours of inactivity before you hit a session timeout:

<?
ini_set("session.gc_maxlifetime","14400");
?>

HTH  - Jonathan
Avatar of cracky
cracky

ASKER

Thanks for the heads up.

I have changed the session.gc_maxlifetime using ini_set() and I will now time the session to see if it lasts longer. The previous value was 1440, which in seconds equates to 24 minutes as you mentioned.

However, I don't know how I am going to get around the following PHP manual explanation for ini_set():

"The configuration option will keep this new value during the script's execution, and will be restored at the script's ending."

If it is reset at the end of the script, how will it set the new value for the length of the session?

Anyway, I will get back to you to let you know if it works.
Yeah, I thought about that. You may need to change it in the php.ini file or see if you can put a PHP directive in a .htaccess file (you can do it, depending on your setup).:

http://www.php.net/configuration.changes

The actual directive for the .htaccess file would be something like:
php_value session.gc_maxlifetime 14400

And of course, this will only work if your web host has you set up with the ability to use .htaccess files and also with the ability to use PHP configuration settings in that file.

However, you may also be OK with just the ini_set. It seems like the gc process only runs when you request a page - but it might run before you get to any code, so who knows. It might work and it might not. We'll see.

- Jonathan
Avatar of cracky

ASKER

ini_set() failed to work, but I have the ability to use it in .htaccess with my host.

<IfModule mod_php4.c>
  php_value session.gc_maxlifetime "14400"
</IfModule>

Their examples had values between quotes, so I tried it that way.
Avatar of cracky

ASKER

Directive has been set in .htaccess and phpinfo() shows 14400 as the Local Value for the session.gc_maxlifetime using the directive:

<IfModule mod_php4.c>
  php_value session.gc_maxlifetime "14400"
</IfModule>

So obviously the directive is working, but guess what? The session still times out. I am seriously thinking about canning the idea altogether and storing the login and password with a hash value in a cookie. I have seen other sites do this and it's reasonably secure.
Don't give up!

Never let it beat you! :-)

There are many configuration variables that affect sessions. It's possible that your cookie is expiring before the gc_maxlifetime.

You can read the values of all of these variabels with ini_get(). The whole list of directives and all the detailes are at:
http://us4.php.net/manual/en/ref.session.php

I would check specifically:

session.cookie_lifetime
session.cookie_secure
session.use_cookies
session.use_only_cookies
session.referer_check

Check all these values with the dedcitpions on the above manual page.

I'm sure that you can solve this problem and use cookies in your admin section. Sessions are much easier to deal with than cookies code-wise. MHO
I agree with psycle. Sessions are the more manageable way to go. Have you determined how many minutes it takes to time out? Also, have you tried any other browsers (i.e. Opera) to see if they time out at the same rate?

There's also the uglier, but functional option of having a small piece of Javascript that reloads an invisible page so that the session stays active. Keep in mind that you'll have to pass the session ID (usually $PHPSESSID) as part of the query string when you refresh - otherwise if you refresh w/o the session ID, it'll kill the session.

- Jonathan
Avatar of cracky

ASKER

session.cookie_lifetime 0 (until browser is closed)
session.cookie_secure Off
session.use_cookies On
session.use_only_cookies Off
session.referer_check no value

Does anybody have some ideas on these settings? Thet all seem right to me :(

I have turned use_only_cookies on to see if that will help ...

Gotta keep trying, thankls for your help :)
Avatar of cracky

ASKER

Still no joy.

Points increased to 500.

I'll keep trying options to see what comes of it.
SOLUTION
Avatar of psycle
psycle

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cracky

ASKER

1) This is true.
2) From what I know, this is very insecure, since the session variable can be passed to another user in a URL and validates the new user automatically.
3) I use Mozilla 1.4, but both Moz & IE6 have the same problem.
7) I will try this.
8) Yikes!

session_set_save_handler() looks promising, I'll see what I can do with it.

The time difference is huge, since my server is in the U.S. and I am in Australia, but I wonder what difference this will make, since times in the cookie are set according to loac time on the client?

I'll leave the Q open for a while to see if I get any other ideas. Thanks to psycle & Jonathan for their help so far!
In regards to number 2:

"2) From what I know, this is very insecure, since the session variable can be passed to another user in a URL and validates the new user automatically."

This no more insecure than cookies. Think about it logically for a minute... How many ways can you think of to get someone else's session id number? If you were sniffing network packets you could get it from the cookie just as easily, so that's not an issue. There is no way to accidentally pass a session to a another user at the same time becasue php will not assign an existing session id to a new user if it already exists. About the only way I can think of to steal soemone's session id is if you are standing behine them and see it ...and you would also have a to have an amazing memory to memorize it. Besides, if someone is visiting your site who doesn't accept cookies the session id is going to be appended to every url anyway if you have trans sid enabled. Also, when you first get to your site and land on the first page that starts a session, the session id is automatically appended to all the urls until the cookie is available on the next page (cookies are not available until the next time headers are exchanged). ...so in a nutshell, you are probably already doing it anyway.

If you use session_set_save_handler() you can write code into your fuctions to get the user's IP and save it in the same table as their session data. Then you just check that they have the same ip throughout the term of their session. If it changes, you assign a new session as if they were a new user. This will stop session hijacking in its tracks. You can also write code into your functions to check the referer to make sure that's good too. Anything can be hacked, but if you make it harder by using multiple layers of protection it's less likely that hacker will be willing to waiste time just to see one person's silly account information. Also, by using mysql to store session data, no one will be able to read session files in /tmp.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cracky

ASKER

Thank you both very much for your suggestions, you have been very helpful in guiding me to an option that works best. I will split the points to both of you for the help you have given so far and keep you updated by posting updates of how I (hopefully) come to tackle the issue.

Cheers!

Bodog.
Not everyone needs to be worried about packet sniffing.  The question is, can we make a session "permanent" with PHP built-in fuctions, or do we have to custom-write our own routine to set a cookie with login info and re-register the session?  Since PHP has so many high-level abilities, can we make a session which does not expire?
Come to think of it, I don't think you can make a session that does not expire. If I recall correctly, sessions generally last until the browser is closed or something else interrupts and restarts the session. While you could possibly force the session cookie to stay active for a long while, server-side garbage collection may clean up your session data before you can use the cookie again. You could possibly tinker around with the garbage collection settings if you had access to the main PHP settings file, but not everyone has that ability.

If you want a longer-lasting "session" without using PHP's session functions (especially if you are writing a script that you are going to sell or distribute), I believe it would be best to use cookies:
http://www.php.net/manual/en/function.setcookie.php

- Jonathan
Does anyone have a small routine that can set a cookie with the session information and re-establish the session?
About expiring.
I use iframe pages, so I made the following:
In main pages (I have admin page and user pages)  - I make the following check:

      if (!isset($_GET["sessionName"])) Header("Location: index.php");
      session_name($_GET["sessionName"]);
      session_start();
      if (!isset($_SESSION["user_id"])) Header("Location: index.php");

In iframe pages:

      if (!isset($_SESSION[$_SESSION["user"]."_id"])) {
?>
      <script>
      window.parent.location.href = '<?php echo ($_SESSION["user"] == "user" ? "index.php" : "indexa.php") ?>';
      </script>
<?php
      }


Btw, I have a problem with sessions, too.

Everything went well until there was no request from a client to enable both admin and user to log-in in the same browser on different pages.
The thing is that admin and user use the same page, that just differs in some places of code.

Ok, what I had to do - to assign session name. Since no more than 2 user were supposed - I add "admin" and "user" session names and drag them everywhere via URL :)
But other problem arised: if the use didn't make logout (that destroyed the session) and just typed the same index.php again in URL, being on main.php page - what would happen? Should I foresee such situation and add some session pre-destroying code to index.php and indexa.php (for admin) pages as well?

Hmm........