I'm developing a site for someone where users can post problems to a website and the Admin of the company can view the problems and give a solution for it. I use one page that takes care of the login handling and a mysql db. The problem is that i can log in, it shows me another panel(userpanel), but whatever other button i click, it takes me back to the login panel.
It used to work as i was able to post data to my database. but suddenly after some changes on my website, it stopped working (and i can't find the problem anymore.)
When i log in, $_SESSION["LoggedIn"] gets a value and goes to the other panel on the same page with http post. when i click a button there, it seems that $_SESSION["LoggedIn"] is removed again because i check with isset if the user is logged in, otherwise it shows the userpanel.
//check user logged in
if (isset($_SESSION['LoggedIn'])) {
//Problem posted
if (isset($_POST["plaatsen"])) {
//Processing - plaatsen
postProblem();
}
} else {
//do login thing
}
I've attached my code here and i hope anyone can help me out.
Index.php: http://pastebin.com/BZSirUTT
Functions.php: http://pastebin.com/7Hknhm9r
Website: http://php.olvgroeninge.be/~sac.26A-07/php/Oefeningen/Oefening3/index.php (it's in dutch)
Sessions typically don't disappear by themselves. If they do, assuming you did run session_start() first, it can be due to:
The session could not be saved on the server; this can be due to disc space or permission issues. It could also be due to any page output before the session_start() statement. Fortunately, you can see this by heightening the error reporting at the start of your script:
ini_set('display_errors', 'On');
error_reporting(-1);
The session could not be found; for session to perpetuate it requires the session id at every request. Depending on your settings, this can come from the URL (PHPSESSID=xxx) or cookies. In the latter case, you can verify that your browser sends the cookie by whipping up the browser developer tools.
You destroyed the session yourself; calling session_unset or session_destroy will clear and remove the session respectively. Make sure this doesn't happen accidentally.
The session is garbage collected; this normally only happens after some time of inactivity, configured using the relevant ini settings
The session could not be read; just like #1 but for reading.
Hope at least one of these points helps you.
Debugging the session
You can add the following code to all pages to isolate the problem:
echo '<pre>', htmlspecialchars(print_r($_COOKIE, true)), '</pre>';
session_start();
echo '<pre>Session = ', session_id(), '</pre>';
Update
The problem is that the index.php doesn't set any cookies; OP created a separate small test page which does set cookies. Turns out the problem is #2 then :)
Related
My PHP Sessions are giving me yet another headache.
I have just created a log-out page in my PHP code.
when the user clicks on the link, he is logged out of the system.
I got my code from several PHP manuals online.
The code works fine. No problem.............except for this : when the user logs back into my website, the previous session has been wiped out! Meaning, when the "Main page" displays, it is missing almost all the necessary variables (such as : firstname, lastname, etc...........mostly, the user's data, which he creates when he REGISTERS or the first time)
The registration itself is done in my INDEX.PHP file (which is where I initiate the session : SESSION_START()
From there, the user is taken to the LOGIN-PHP file (where he logs in for the first time)
After that, all is well.
However, once he logs out.............and then tried to log back-in, all the variables have vanished. !
I suspect that the problem is caused by the way I wrote my PHP code in the LOG_OUT.php file :
<?php session_start();
unset($_SESSION);
session_destroy();
session_write_close();
header("url=http://localhost/return_to_main_page.html");
die;
exit;
?>
Perhaps, using : UNSET, DESTROY, CLOSE, EXIT, DIE.........all at once, may be a bit of an over-kill??? :)))))
(Kinda like shooting a mouse with a rocket-launcher)
Not sure.
"Any-hoo", my point is :
(a) The entire process works from A to Z, but only IF everything is done in sequence ---- registration, log-in, do-your-stuff, log-out, etc. But, after that, if the user tried to log back in, the session is "cut-off"
(b) Obviously, this is silly. A user should be able to log back in whenever and wherever he wants. (What if he registers his account on a computer at home, and tries to log-in on another computer in Australia? DOH !)
I can't find anything similar anywhere on google, or such. My guess would be : my problem is so silly, and hence the solution is too obvious, that nobody has ever encountered this before
Doing session_destroy() and unset ($_SESSION) and etc. may be a little overkill.
instead, just do:
<?php
session_start();
session_destroy();
header ('location:http://localhost/return_to_main_page.html');
?>
That's what I do in my logout scripts.. It should work.
If not, let me know.
Please help me out to clear login session.
For example
If I am a user of a particular & I want to check my updates. So I used my user id & password to login to the particular page.
After checking my updates I logged out from the page. After logging out, I used back button in the browser to go back to previous session.
Automatically enters into my page without giving any login details. To prevent from entering into page without any login details the session should be cleared. So help me out to clear the session.
This is a client side problem. If you press back button in browser, the browser loads the previously stored cached page.
Better way is, You should write a javascript function in login page which invokes logout.jsp whenever loaded first time or through back button.
You need to set the cache control header on your pages to ensure they are not cached. Since Have a look at the following question which goes into detail about how to set the cache header correctly in different languages - How to control web page caching, across all browsers?
To clear session in php, you can call a script logout.php containing the following :
<?php
session_start();
$_SESSION = array();
// PHPSESSID is default name, but you may have a custom.
setcookie("PHPSESSID", '', time() - 1, '/');
}
See a more complete example at
http://fr.php.net/session_destroy
I don't want the user to go back to secured pages by clicking back button after logging out. In my logout code, I am unsetting the sessions and redirecting to login page.But, I think the browser is caching the page so it becomes visible despite the session being destroyed from logout.
I am able to avoid this by not allowing the browser to cache
header("Cache-Control", "no-cache, no-store, must-revalidate")
But this way I am loosing the advantage of Browser Caching.
Please suggest a better way of achieving this. I feel, there must be a way of handling this by javascript client side
Implement this in PHP and not javascript.
At the top of each page, check to see if the user is logged in. If not, they should be redirected to a login page:
<?php
if(!isset($_SESSION['logged_in'])) :
header("Location: login.php");
?>
As you mentioned, on logout, simply unset the logged_in session variable, and destroy the session:
<?php
unset($_SESSION['logged_in']);
session_destroy();
?>
If the user clicks back now, no logged_in session variable will be available, and the page will not load.
I was facing this same problem and spent whole day in figuring out it,
Finally rectified it as follows:
In login validation script if user is authenticated set one session value for instance as follows:
$_SESSION['status']="Active";
And then in User Profile script put following code snippet:
<?php
session_start();
if($_SESSION['status']!="Active")
{
header("location:login.php");
}
?>
What above code does is, only and only if $_SESSION['status'] is set to "Active" then only it will go to user profile , and this session key will be set to "Active" only if user is authenticated... [Mind the negation [' ! '] in above code snippet]
Probably logout code should be as follows:
{
session_start();
session_destroy();
$_SESSION = array();
header("location:login.php");
}
Hope this helps...!!!
Here's an easy solution which I have used in my application.
Add the below code inside script tag in the login HTML page (or whichever page it redirects to after logout)
<script>
history.pushState(null, null, null);
window.addEventListener('popstate', function () {
history.pushState(null, null, null);
});
</script>
It will disable the back button. You will not be able to go back by clicking on the back button.
Note: Not tested on Safari.
I think your only server side option is to disallow caching. This is actually not that bad if you are using a Javascript heavy application as your main HTML might only be a series of JS calls and the Views are then generated on the fly. That way the bulk of the data (JS MVC and core code) is cached but the actual page request isn't.
To add to the comments pasted below I would suggest adding a small AJAX call during load time that fires even for cached pages that goes to your backend and checks the session. If not session is not found it would redirect the user away. This is clientside code and not a secure fix, sure, but looks nicer.
You could get this off your conscience with
A cheap fix if all else fails would be a "Please close this window for security reasons" message on the logged out page. – izb May 9 '12 at 8:36
But like N.B. said
You don't have to disable anything. If they go back, they're served the cached version of the restricted page. If they try to click around it, nothing will work because the appropriate session won't be set. – N.B. May 9 '12 at 7:50
You could insert a condition/function on each restricted page, checking if the appropriate session variable is set or not. This way, you can print 2 versions of the page (one for the valid users, and one redirecting to the login page)
Avoiding the user to go back is not a good reason and most of all not secure at all.
If you test the user's session before every "admin" action made on the website, you should be fine, even if the user hit the back button, sees the cached page and tries something.
The "ties something" will return an error since the session is no longer valid.
Instead, you should focus on having a really secured back office.
Here's an easy and quick solution.
To the login form tag add target="_blank" which displays content in a different window. Then after logout simply close that window and the back button problem (Safari browser) is solved.
Even trying to use the history will not display the page and instead redirect to login page. This is fine for Safari browsers but for others such as Firefox the session_destroy(); takes care of it.
the pages on which you required loged in, use setInterval for every 1000 ms and check wheather user is logged in or not using ajax. if user session is invalid, redirect him to log in page.
Note that although users can't change anything after resetting session data and/or cookie, they still may see usual information accessible to a logged in user as they appeared on the last visit. That is caused by browser caching the page.
You have to be sure to add the header on every page accessible by a logged in user, telling the browser that the data is sensitive and they should not cache the script result for the back button. It is important to add
header("Cache-Control: no-cache, must-revalidate");
Note that those other elements other than the immediate result of the script under this header, will still be cached and you can benefit from it. See that you gradually load parts of your page and tag sensitive data and the main HTML with this header.
As the answer suggests, unsetting the logged_in portion of $_SESSION global variable can achieve logging out, but be aware that first, you don't need to destroy session as mentioned in the PHP's session_destroy() documentation
Note: You do not have to call session_destroy() from usual code. Cleanup $_SESSION array rather than destroying session data.
And second, you better not to destroy the session at all as the next warning on the documentation explains.
Also, unset() is a lazy function; meaning that it won't apply the effect, until next use of the (part of the) variable in question. It is good practice to use assignment for immediate effect in sensitive cases, mostly global variables that may be used in concurrent requests. I suggest you use this instead:
$_SESSION['logged_in'] = null;
and let the garbage collector collects it, at the same time it is not valid as a logged in user.
Finally, to complete the solution, Here are some functions:
<?php
/*
* Check the authenticity of the user
*/
function check_auth()
{
if (empty($_SESSION['logged_in']))
{
header('Location: login.php');
// Immediately exit and send response to the client and do not go furthur in whatever script it is part of.
exit();
}
}
/*
* Logging the user out
*/
function logout()
{
$_SESSION['logged_in'] = null;
// empty($null_variable) is true but isset($null_variable) is also true so using unset too as a safeguard for further codes
unset($_SESSION['logged_in']);
// Note that the script continues running since it may be a part of an ajax request and the rest handled in the client side.
}
I have a PHP website I'm maintaining and I've confirmed that this worked at one point.
We have a website utilizing a login system which stores a logged in user's information in a $_SESSION['user'] variable. The site used to log out the user when clicking /logout.php which essentially removed that portion of the session, then header() redirected to the homepage.
As of recently, the /logout.php file with session_start() at the top somehow doesn't see the session information when print_r() is used to output it for debugging purposes.
If I go to another page, I see the session info just fine, but not on the logout page...which is exactly why I cannot remove the session info, because it's not accessible.
I thought $_SESSION was global on the site until the browser was closed. I've never had this happen and I know the session instance was started on this page, so it's weird that it's not showing me the session data.
Any ideas? I'm totally stumped on this one!
Code: /logout.php
<?
#session_start() is inside this file
require_once($_SERVER['DOCUMENT_ROOT'].'/includes/config.php');
unset($_SESSION['user']);
header("location: /");
exit();
?>
The checking of $_SESSION['user'] is site-wide and I call to various items below it when needed for different things. Someone else built this site and I'm trying to debug why it's not working for them all of a sudden.
If the domain/subdomain is the same as the rest of the page, I would say this sounds like a typical session vs. output error. Make sure you have enabled all errors, and display them, as you might have printed output to the client before calling session_start(). This will break the function and making sessions unavailable.
To fix the problem(if it is the case), you should remove all output before session_start. Even a space before <?php will be considered output by Apache(and other). Also make sure you have disabled BOM(Byte Order Mark) in the document(any decent editor will let you change this, just look for something like "Current file setings").
Always remember the first line of your PHP code should be session_start(); and nothing else. If all your going to do is unset the session variables and destroy the session, Try removing the require_once($_SERVER['DOCUMENT_ROOT'].'/includes/config.php'); and add the session_start() and the session_destroy() at the end of the logout.php file and see if it works.
Are you accessing logout.php from the same exact domain that you set the session to begin with (i.e. example.com vs. www.example.com/logout.php)
As for just unsetting specific session data, it would be best to call session_destroy() and then unset your cookies to kill the session.
Caching the HTML output of non-important pages (like blog posts) really helps to speed up a site by skipping the loading of the entire system (and rendering time) and just spiting out a pre-made copy of the page. This would be one way you can keep large waves of users to your site index or whatever from eating resources.
However, one of the problems of caching pages is that in order to check wither or not you can show the page - you have to load the entire system (and the user lib) to check if the user is logged in. (Wordpress, CodeIgniter, Drupal, etc..)
Then you can determine if it is safe to show a cached version of the page or if you should re-render the page for the logged in user. And vis-versa; a page rendered for a logged-in user shouldn't be shown to a guest!
Anyway, I finally had an idea that I could just use if(empty($_COOKIE)) to test for a user session since I never use the URL to transfer the session ID. Then I remembered that since the session library is loaded on each page that probably won't work since it will create a cookie when session_start() is called.
Does anyone have any ideas about how to test for a user session without loading your database connection -> for your session library -> for your user library?
I just recently learned this, so I hope I have everything straight.
In order to access saved session variables, you have to have a session started. In the project I'm working on, the 'user login' and 'create new user' pages all start out with session_start(). I also tried testing if the cookie was set, which didn't work too well. If the user is logged in or not, it doesn't matter, because there will be a cookie for both guests and logged in users. If you have a session then you'll have a cookie (provided that's how you have php setup, which sounds like you do). So instead of testing the cookie, I test to see if a session variable is set. This variable will only be set once the user successfully logs in.
if (loginSuccess()) { $_SESSION['login']="true"; }
After this, I can now test to see if that session variable is set, and display content appropriately. My user can navigate away from those pages, come back, and it will still remember that session variable.
I'm sure there are better, secure ways of doing this though.
You could set some kind of session variable once the user logs in, i.e.
//user has successfully logged in
$_SESSION['logged_in'] = true;
Then, somewhere very early in your page load (before any libraries have loaded) you could do:
#session_start();
if(!(isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true))
{
//not a logged in user, show the cache!
load_cache(); //or however this works
exit();
}
On a logout, you'd either do session_destroy() or $_SESSION['logged_in'] = false;
Yes, as I stated the current method involves loading the system, database (assuming your sessions use the database), and finally starting the session which is a waste if you are only going to show cached content.
Perhaps you could set a cookie called "logged_out" (or "logged_in") in addition to the session cookie. Then you could test for "logged_out" cookie on each page load without the need to load the session and database?
Actually, since you would have bots and other non-cookie user agents you it would be better to create a "logged_in" cookie on login and then everywhere else check for a false/non-existent cookie as a sign for a guest.