I developed a web application that allows both entrepreneurs and customers to log in through two different login portals. I developed the application locally, using a XAMPP, i.e. Apache, configuration. There, it worked perfectly.
I am now trying to have it run on a Lighttpd web server which works OK. I'm running into a weird issue. If I use the customer login, everything works fine, the session gets created, and the customer keeps having access to his account data.
When I login through the entrepreneur portal, something strange happens. When I var_dump()'d the $_SESSION variable, directly after logging in shows me the session object correctly. When pressing F5, or navigating to another page in the portal, the $_SESSION variable gets destroyed and var_dump($_SESSION) shows an empty array.
I found Why PHP Session Destroyed? that proposes a solution to fix Lighttpd destroying sessions. I assume that is not the problem, as my sessions work at one login portal, while not at the other.
Does anyone have a clue why my session gets destroyed?
This is how I set my session variable:
$_SESSION["ll_oid"] = $q["id"]
(where $q["id"] is the entrepreneur ID)
And this is how I check it:
$id = $_SESSION["ll_oid"];
if($id == null) {
session_destroy();
header("Location: index.php");
die();
}
At all pages, session_start() is called before any headers are sent.
Related
I am setting up an admin panel for a website, and everything was working fine on my local (MAMP) server. I uploaded the website to the server and the user authentication isn't working anymore. I am able to get a success from the server, but when I'm entering into a page, PHP can't find the required session variable, and thus redirects the user back to the sign in page.
I have tried on both PHP version 5 and 7.
I have tried echoing the session variable upon verification.
I have tried to simply store the variable on one page and reading it on another page in the same folder, and it didn't work as well.
page1.php
<?php
session_start();
$_SESSION["userid"] = 1;
?>
To Page2
page2.php
<?php
session_start();
if (!isset($_SESSION["userid"])) {
header("Location: page1.php");
die();
}
echo $_SESSION["userid"];
After I click the link in page1.php, page2.php redirects me to page1.php again without any error.
Is your website using some load balancer?
By default, PHP creates the session on server memory. So, if your website is using a different server for each request, the $_SESSION set values are lost. In this case, a good solution could be store sessions out of the server, maybe in a Redis or Memcached.
I'm working on a fairly basic project that, within the scope of the question, contains a few PHP files.
session.php::session->checkSession()
if (!isset($_COOKIE["session"])) {
$this->redirect("login/?h=t"); //Redirect to login page
}
The checkSession function is called on every page load within the web app.
On every page everything works fine, however, on one page, the user is redirected to /login/?h=t (I added the 'h=t' bit for the sole reason of differentiating between other places where the user is redirected to the login page. When I create a debug script that just does var_dump($_COOKIE);, I get the cookie array which does contain the session cookie.
I have run out of things to test since the code says that the cookie does not exist, yet the same code says it does exist.
UPDATE: Clearing cookies in the browser fixes the issues temporarily.
I have an application where the login and logout works correctly. Once the user logs out, and tries to access a page he needs authentication for, he is redirected to the login screen.
Where my problem lies is. If while I am logged in, if I copy the cookie values and save them on a file. After logout, I alter the cookie and add the same values, I get logged back in into the application as the same user.
On logout I have written a function that loops over all the cookies and deletes them.
My understanding is that cookies are both on the client and also on the server side. So if the cookies are getting deleted, they are getting deleted on both the sides and that the server would not recognize them after they have been cleared, even if the browser sends them back again(apparently that is not the case, i think).
The reason why I am doing this is because this is one of the points raised by our security auditor, and I need to get a way to fix this hole. (At this point doing https is not feasible)
I'd be happy if someone can give me pointers on how I can clear out the cookies on the server side as well, so, when the next time someone hits the server with the same cookie, it does not accept it as a valid cookie.
Edit:
I am using codeigniter sessions and tank_auth as the authentication library. At logout, the library itself calls
$this->ci->session->sess_destroy();
to be extra sure, I tried the following after a few attempts :
session_start();
session_unset();
session_destroy();
session_write_close();
setcookie(session_name(),'',0,'/');
session_regenerate_id(true);
My regular logout works, and if I try to access the page directly it does not open.
But if while I am logged in, I take my cookie, save it somewhere -- log-out successfully and replace the cookie with my older one, I get right back into the session.
Is there a way to stop this behavior -- Where the server side will not entertain a session after it has been destroyed. I also made sure that my server and php are on the same timezone (setting it with date_default_timezone_set).
Cookies are not stored on the server at all. Those are stored in the browser and then sent to the server in the request headers. You can easily find software and plugins for browsers that allow you to create/edit/delete cookies. For that reason you should never store sensitive information in cookies. Essentially what you want to do is store the user data in a session and then store the session name in a cookie. Usually this is done automatically in php when you use the function session_start().
If you are using Codeigniter, the php session functions are wrapped in a CI session library that is auto loaded on each page load. So instead of storing data in $_COOKIE you will want to get/set your data via the userdata method in the session library:
//in your controller
//save session data
$userdata = array(
"isLoggedIn"=>true,
"username"=>$_POST['username']
);
$this->session->set_userdata($userdata);
//get session data later
$isLoggedIn = $this->session->userdata("isLoggedIn");
if(!$isLoggedIn){
//if the user is not logged in, destroy the session and send to the login screen
$this->session->sess_destroy();
redirect("/");
}
Note that the code above is not tested and is only supposed to give you an idea on where to go. If the session methods aren't working for you, you may need to load the library in manually:
//in the __construct method of your controller:
$this->load->library("session");
You can find more information here:
http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
and here:
http://www.php.net/manual/en/book.session.php
Thanks for you answers guys.
This is what I figured, later. I am not sure what was causing this but the sessions were not getting invalidated after trying everything. I moved the sessions on codeigniter to the database. Then the logouts started working correctly, where after logout if the 'stolen'/'saved' cookie was put in the browser again it would Not log the user back in.
So, thats what solved it.
Some problem is coming when I am uploading site to online server. User authentication was working on my local computer but when I am trying to upload it to a server, it is not working. When I sign in, it redirects me back to the login page.
I have checked out and come to the point that when the page refreshes, the user info from session flush away and it redirects back to login page.
$this->setState('username', $user->username);
setState method is also not giving information on next page.
Please help me out with possible solution.
Thanks
Make sure that you session was started automatically in php.ini config "session.auto_start = 1" or it was started manually by session_start() or Yii similar function
$session=new CHttpSession;
$session->open();
And check your session status by session_status() function.
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.