I'm having a difficult time with PHP doing some very basic session security type of things:
A new session ID should be generated when switching from a non-authenticated context to an authenticated one
A new session ID should be generated when switching from an authenticated context to a non-authenticated one
What I'd like to do is not only regenerate a session ID when switching contexts, but also immediately put something into the session (such as a FLASH) when switching those contexts. These three pages should hopefully clarify my expectations:
<?php
/* page1.php */
session_start();
# Just putting something in the session which I expect to
# not show up later
$_SESSION['INFO1'] = 'INFO1';
?>
<html>
Page 2
<?php print_r($_SESSION) ?>
</html>
So when this page is displayed, I expect to see INFO1 show up. I also expect when I come back here NOT to see INFO2 show up. If I don't already have a session ID, I expect to get one (I do).
<?php
# page2.php
session_destroy();
session_regenerate_id(TRUE);
$_SESSION['INFO2'] = 'From page 2';
session_write_close();
header('Location: page3.php');
exit;
?>
This would be most akin to a logout function - we invalidate the existing session by passing TRUE to session_regenerate_id. Also, I put something in the (presumably) new session - which may be like a FLASH - say "You've been logged out successfully.
#page3.php
<html>
<body>
<?php session_start(); ?>
<?php print_r($_SESSION); ?>
</body>
</html>
On this page, I'd expect two things to happen:
The redirect from page2.php should have sent me a new session ID cookie (it did not)
I'd expect for the print_r to print information from INFO2, and not from INFO1. It doesn't have information from INFO1, but does not include information from INFO2.
I've had very, very inconsistent results with session_regenerate_id and redirects. It seems like such a kludge to manually send that Set-Cookie header - but even if I didn't, session_regenerate_id(TRUE) should invalidate the old session ID anyhow - so even if the browser didn't for some reason get the new session ID, it wouldn't see any information in the session because the old session had been invalidated.
Has anybody else had experience with these sorts of issues? Is there a good way to work around these issues?
Based on the documentation for session_regenerate_id, it sounds like the contents of the session are always preserved. You're passing it a TRUE argument, but that only deletes the actual session file on disk; the values stored in it are kept in $_SESSION and then written to the new session.
So perhaps wipe it out manually:
$_SESSION = array();
Not sure why you aren't seeing the new cookie, though. Where did you check, what did you see?
edit: The problem, as revealed by the OP in a comment below, appears to be that page2 never called session_start to load the first session. Which produces the following:
<?php
session_start(); # Load the old session
session_destroy(); # Nuke it
session_unset(); # Delete its contents
session_start(); # Create a new session
session_regenerate_id(TRUE); # Ensure it has a new id
$_SESSION['FLASH'] = "You've been logged out";
session_write_close(); # Convince it to write
header('Location: index.php');
?>
I have no idea if this is minimal. Figuring out how much of it can be deleted is left as an exercise to the reader.
Related
i have searched and searched and read and read a lot about what exactly session_destroy does ! but no result at least for me ! first read the details below :
When a session is created (session_start) a file is created with a
unique identifier that is given to the user as a cookie, when
variables in the $_SESSION array are modified or added the temporary
file is updated with that information so that it can be used somewhere
else on the website.*
session_destroy* will delete this file, this is commonly done for when
a user logs out of your website so that the (now useless and
unnecessary) file isn't taking up space.
we know that session id is stored in session cookie and as the tutorials say , session destroy removes the session cookie file (that includes session_id ) so why when i started a new session it didn't generate a new id ! it makes me confused ! look at the example :
<?php
session_start();
echo session_id();
session_destroy();
session_start();
echo "---".session_id();
?>
result : l4k80dkrl5kd6cdlobhbu5s3i1---l4k80dkrl5kd6cdlobhbu5s3i1
so it gives me the session id same as the previous one .
so what does session_destroy really do !! ?
thanks in advance
From PHP documentation:
It does not unset any of the global variables associated with the
session, or unset the session cookie.
So after session_destroy() the cookie that holds the session id is still alive, and just the session file will be deleted. So start_session() tries to find the file for the session id in the cookie, and it fails of course, and it just creates a new empty file for that. So your id does not change.
If you really want to change that, try to delete the cookie.
You are almost correct about what you have said, BUT if you destroy the session and the script ends in PHP, thats the time file is deleted. If you just try to destroy and create it again, it uses the same file/session ID.
Its not only the file that is created, but also the file contains all the data you are storing in the session. Have a look at your session data in your server, its very interesting.
Update
More interesting things you can do. Write a PHP file
<?php
session_start();
sleep(29000);//delete the session after 29 seconds
session_destroy();
?>
Now have a look at the session file, it should be deleted after 20 seconds.
Do
<?php session_start(); ?>
and go to google chrome, and remove the cookie manually from there. The session won't be available anymore.
<?php session_destroy(); ?> will not destroy the cookies on the
client side. Next time you create a session, it will just use the same
old information. This is the prime reason of your question.
Do
file1:
<?php session_start(); $_SESSION['test'] = "A"; ?>
file2:
<?php session_start(); $_SESSION['test'] = "B"; ?>
resultFile:
<?php session_start(); echo $_SESSION['test']; ?>
Now from two computers, access your website with file1 on one computer and file2 on another. From google chrome, switch their cookie information and see how session A is assigned to B and B is assigned to A.
I have implemented session into my application, but I need to allow the logged in user to use the back button to go to the previous pages.
How do I make sure that the session does not expire and allows the user to view the previous page?
Here is my code
<?php
//Start session
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start();
}
$User = $_SESSION["User"];
//Page content
?>
I have started the session, when I use the back button on browser I get a page that reads session has expired. Which I do not want to happen.
in your php at the top of each page, start your session before your opening <html> tag
<?php session_start(); ?>
<html>
in your php somewhere set your session variables note this value must be serializable
<?php $_SESSION["variable"] = "value"; ?>
then anytime you want to access that session variable you can do the following AFTER calling session_start();
<?php echo $_SESSION["variable"]; ?>
if you handle your sessions in this manner, session variables will be available on previous and future pages.
caveat:
depending on browser and headers sent from your server, when you go back a page, it reloads the page as it was in the cache so consider the following:
User goes to page and is does not have a session variable set
User does action that sets a session variable and sends them to a second page
User hits back button
User is shown the pre-session cached version of the first page
User refreshes page
User now sees the first page w/ session variable set
the reason for the hiccup is that some browsers do not always make a new request on back button sometimes it loads from the browser cache. read the very end of this answer: https://stackoverflow.com/a/1313941/884453
EDIT
You posted code above with a check to session_status first. This is incorrect. You ALWAYS need so session_start();
<?php
//Start session
session_start();
// User is either pulled from the session or is null
$User = $_SESSION["User"] ? !empty($_SESSION["User"]) : NULL;
//Page content
?>
the code for if (session_status() !== PHP_SESSION_ACTIVE) { is only useful in situations where some other bit of code (usually in a framework) may have started the session already.
If you have set up your session management correctly, you don't need to do anything.
However, this correctly depends on what kind of state you have in the session and how you manage it. Also timeouts will still apply (as they should).
You can use javascript history method also for that so your session also remain same.
<button onclick="goBack()">Go Back</button>
<script>
function goBack() {
window.history.back();
}
</script>
i'm having a bit of a problem. I'm trying to set up a simple webpage with only three .php pages. I want a session variable $_SESSION['userID'] to be set when a user is logged in and I want the index page to show extra info if someone is logged in.
On index.php I want to show some info, if a user is logged in I want to show some extra info.
login.php - simple log in form.
login_exe.php - takes care of database connection and verification.
So this was my idea:
On index.php, check if session is started, if not: start.
<?php
if (!isset($_SESSION)) {
session_start();
echo "session started";
}
later on, check if $_SESSION['userID'] contains a value, if so: print a string
if($_SESSION['userID'] != null){
echo "User logged in";
}
On login_exe.php i've almost the same code:
<?php
if (!isset($_SESSION)) {
session_start();
echo "session started";
}
in verification function:
$_SESSION['userID'] = $data['userID'];
header("Location: index.php");
The problem is that a new session is started on every page. How can I fix this and only start the session once? Thanks in advance
You should just put session_start() on top of documents that using sessions. Say, if you have 5 .php files that using sessions, then put 5 times the session_start() on top of them.
This is because session_start() sends headers and headers must be sent before any output (for example, any echo or whitespace).
Then, you should use something like isset($_SESSION["foo"]) and not just the entire $_SESSION array, where foo is something you set previously.
If you dont want sessions at all or need to reset the entire array, just call session_destroy() which effectively destroy the current session. Use unset($_SESSION["foo"]) when you want to get rid of a key.
Finally, you might get weird cases where you cannot read session key you write at. In these cases check what is the path of sessions and if they're writeable, or change their path:
$path = session_save_path(); // what is the path
is_writable($path); // can i write to it?
session_save_path("my/new/path"); // change the darn path;
// put -even- before session_start()!
:)
glad i help
I think the PHP manuals are really good compared to ...ahm, so just read about session_start(). It says:
session_start() creates a session or resumes the current one (...)
so all you need is session_start() very early in your code. This must be executed on every request (maybe as include).
Your code checking the userId looks fine, one important hint here: you should know exactly what isset(), empty() and the like mean in PHP, so always have the comparision of comparison at hand.
You should not ask new answers (edit: questions) in comments. Be as systematic here as you are in coding.
How to end a session:
This gives room for discussion, because there is the session cookie, which is client side, and the session data, which is server side.
I recommend:
$_SESSION = null;
Reason: this will clear all login and other associated data immediately. It leaves the cookie intact, which is normally of no concern, since all associated data is gone.
Newbie question, but I'm wondering if I'm missing something elementary here.
If I register a session variable in a page - isn't this variable supposed to be accessible from another page on the same site?
First, I register a variable in the file session_var_register.php:
<?php
$_SESSION["myusername"] = 'user';
if (isset($_SESSION['myusername'])) {
echo 'Session var myusername is set to '.$_SESSION['myusername'];
}
?>
When I open this page, it writes:
Session var myusername is set to user
As expected.
Then I open another tab and another page, check_session_var.php:
<?php
if (isset($_SESSION['myusername'])) {
echo 'Session var myusername is set to '.$_SESSION['myusername'];
}
?>
This page is blank.
Isn't the point of a session variable that it should be accessible in the browser session, until the session is programatically destroyed or the browser closed?
I'm using IE 8 and Firefox 24, btw. Identical results.
You forgot
session_start()
On top, before using
$_SESSION
PS: Remember to call session_start() in every page you want to use $_SESSION.
The PHP docs state that you must call session_start() to start or resume a PHP session. This must be done before you try to access or use session variables. Read more here.
session_start();
Your session variables will be available on different pages of the same site but on top of each of these pages you must have at least:
session_start();
It works but not in all cases. You must also use the same session name (essentially a cookie name that stores id of your session) on all pages. Moreover cookies (which are essential (mostly) for sessions to work) may be made visible only in specific directory. So if for example you share the same host with other guys that use sessions too you do not want to see their variables and vice versa so you may want to have sth like that:
1) session_name( 'my_session_id' );
2) session_set_cookie_params( 0, '/my_dir', $_SERVER['HTTP_HOST'], false, true );
3) session_start();
You may also want to see your session variables on other servers and in such case custom session handlers may be useful. Take a day or two to implement yourself - great way to understand how sessions work hence I recommend.
Method
session_start();
Description
session_start() creates a session or resumes the current one based on a session identifier >passed via a GET or POST request, or passed via a cookie.
Usage in your case (and in the most of cases):
Put it before the $_SESSION usage.
Reference: session_start()
First Of all start session on that page
session_start();
your page like this way
<?php
session_start();
if (isset($_SESSION['myusername'])) {
echo 'Session var myusername is set to '.$_SESSION['myusername'];
}
?>
I have a web app I am developing for a school project, I am having issues with the logout page. When a user clicks logout it will send them to a logout.php which just looks like this:
<?php include ("includes/check_authorization.php");
// Unset the session and destroy it
session_unset();
session_destroy();
// Redirect to the home page
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=index.php">';
exit;
?>
It is very simple, but it will unset, then destroy the session, and redirect to the index, which is the login page. However when this is run the index immedietley redirects to a user homepage. The check_authorization page included at the top will redirect someone to login if the username and id are not set and matching in the $_SESSION, so this means that it is setting these for me? I am really confused as to how this is happening. I am using CAS for authentication.
EDIT: the check_authorization.php also initializes the session as well as checking those key values
For like this situation I did as follows, this is working for me all the browsers,
#session_unset();
$old_sessid = #session_id();
#session_regenerate_id();
$new_sessid = session_id();
#session_id($old_sessid);
#session_destroy();
Rather than just unsetting the data, try assigning a dummy value to the session, like:
$_SESSION['authKey'] = '!!INVALID!!';
session_unset();
session_destroy();
Even if the session 'revives', the authentication can't possibly succeed anymore because of the "fake" data.
There are some possibilities :
The most simple possibility : did you include the
session_start();
on top the file? before you include a file? I've been there before, and it pissed me off.
The second possibility : try to put
session_regenerate_id();
on the very top of your file (before you declare session_start();). Because in some Server Hosting, their configuration still using "LINUX" style that i can't explain to you here. But, the point is they always using "cache" when you redirect. In other words, you always redirect into your "cached" page when you rediret to another page. See.. it's hard to explain for you here. But just try the session_regenerate_id(); code, maybe it would work.
I never use the "echo" things in doing redirect things. Try :
header("location:index.php");
i don't know if this working or not. I just simply giving you my analysis based of my assumptions.
Hope these helpful. :)