Showing cached data only to non-members with COOKIE check? (PHP) - php

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.

Related

PHP how to manage multiple session in same browser using cookies?

I'm new to PHP, I read other articles without finding the answer I'm looking for, but still don't know if what I want to do makes sense or not.
I'm using PHP 7.
My user authentication page, checks credentials and then executes session_start(), creating the session server-side and a cookie client-side in the browser.
Each other page of the web application then calls session_start() to resume session information, in this case checking the cookie. Everything works fine so far... at least when I have a single login.
I'd like to be able to have more than one user SIMULTANEOUSLY logged in the same browser (on another tab for example.) using cookie. I don't want to append the session ID to the URL.
I managed to create different session on the server-side using session_id() before session_start() in the authentication page based on username, but the problem is on the client side.
The first successful login (session_start()) creates a cookie and the second login updates the same cookie corrupting the previously created session.
Therefore when it comes to resume the session, session_start() will resume only the last session, mixing the data fetched from DB based on session info.
Is there a way to make session_start() create a cookie for each login and make PHP resume the correct session using cookies?
Any ideas?
FURTHER DETAILS:
I'm updating a legacy app trying to fix some security issue. The need for multiple sessions comes from administrative purposeses where admins access the same site. The reason why it's needed a separation of session is that depending of the session info, the data are fetched from a different database. Therefore, a regular usage would only need one session per user, but the administrator he needs to make multiple logins viewing different data depending on that login.
The default PHP behaviour is to handle sessions using cookies.
..and the default behaviour for browsers is to "reuse" the same set of cookies if you revisit an URL in another tab.. So, like mentioned below:
The simple way probably is to start another browser. Not the same browser but like firefox and chrome, if you have multiple browsers installed.
Another way would be to install a browser plugin, like Sessionbox for Chrome or Multifox for Firefox.
Edit, for clarity: I can think of two cases when multiple sessions would be used:
During development. Depends on the application, but an obvious case would be testing communication between two users.
After deployment. Though I've never seen a site that required multiple logins for the same user account.
This is my frame of reference. Based on this I assumed the question was for development. I'm not suggesting that the site should require installing extra packages. Flash would be about the only one that's ever gotten away with that..
You can use the same session but change the variable names that you are looking for:
if ( $_SERVER['REQUEST_URI'] == '/admin/' ):
$session_name = 'session1';
else:
$session_name = 'session2';
endif;
session_start( $session_name );

Cookie replay after logout php CodeIgniter

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.

CodeIgniter: How to check if session exists when session library is not loaded

I'm working on some website where I need to load session library, but it must be limited only to places on website where it's really useful, not on all. After all that means, the session library must not be loaded on index page. But there is a problem because on index page I need to display user's data if the user is logged in. What can I do to check if the user is logged in, without loading session library or not creating session cookie on index page?
You can't check whether the user is logged in or not if you don't have an active session on your index page.
Your session must exist in every part of the system execution.
Make the session handler always be available but limit the information you store in the sessions instead of limiting locations in the system of where to use sessions at all.

Kill Active Session if User Is Banned

I have set up a login system that checks a mysql db validating username,hashed password, and a banned column (0 means not banned and is the default value, 1 means banned). if there banned they obviously cannot loggin.
The problem is i'm new to php and having a hell of a time trying to figure out how to log out a user who is currently logged in. As it stands now my cookie will last for 2weeks, and even if i ban a user, their session will stay active thus they will have acess for 2weeks or less.
How can i force a user to reauthenticate, without penalizing the masses.
Your server knows what cookie is associated with each user. Why not just delete that cookie from its "current sessions" table?
If the cookie is just "username, who is logged in", you have a real problem, because instead of a magic number, the cookie contains real information, and it becomes trivial to forge. Then a malicious user could simply create a cookie saying "I am [admin], and I am logged in", and that's obviously a much larger problem. So if you can't just delete the session cookie from the "known cookies" table to solve this problem, you have a bigger problem to worry about.
If you are doing your authentication system completely on your own (kudos on that, BTW) you merely need to unset the session value that contains their authenticated status. So, if you used:
<?php
session_start();
if(isset($_SESSION['isloggedin']) && isBannedUser())
{
session_unset();
session_destroy();
}
?>
The pseudo-code above calls to a fictitious function called isBannedUser() to determine if they are banned or not. If they are, in my example above I call session_unset() to unset all values stored within the $_SESSION and then session_destroy() to completely close the session. Some would probably argue that you may not need to unset if you're destroying, but I have just gotten into the habit of cleaning up all variables and values that I make in code.
This should be in every page so that you check if they're banned as frequently as possible. With the $_SESSION destroyed the user is, effectively, kicked out of any part of your website that requires authentication. You will need to implement supporting code in your login workflow that keeps a banned user from logging back in.
Hope this is helpful.
If you are storing the session data in a database, delete the row with their session information. Or, delete the file if using files. Then next page load, the login system shouldnt be able to verify their login information (since there's no info for that session), and prompt them to re-login.
On a file-based sessions system, maintain a counter somewhere which triggers a periodic check of the database for updates, something like:
<?php
session_start();
$_SESSION['hits_since_last_verification']++;
if ($_SESSION['hits_since_last_verification'] > 100) {
$banished = ... // get banishment flag from database
if ($banished) {
$_SESSION['loggedIn'] = FALSE;
}
}
?>
and then decide how long you'd like a banned user to be allowed to continue poking around the site until the session data is refreshed and they get booted.
Another option is an external script which runs through the session storage directory, loads each in turn, checks if the user's banned, and updates the session file as appropriate. But this would be painful on even a moderately busy system as you open/unserialize/check banishment/update/reserialize potentially thousands of session files every X minutes.
maybe you want to store the sessions in another table and delete it when you ban the user.
you know. check the table every time the user load a session and if the user isnt there. delete the cookie and destroy the session (sending him to the index of your site)
You can store the userID in the session and on each request, you check if he's banned (SQL query). If true, you destroy his session so he's forced to reauthenticate. Which fails of course because he's banned.

PHP login user logic

I've scrapped all the tutorials that have never worked for one reason or another, and decided to roll out my own registration/login feature on my own, and to my surprise it actually works!
But what I don't get is how the logic behind keeping somebody logged in works! Like, once they've logged in, do I just $_POST their data to whatever other page they visit and once they're on the new page $_REQUEST that post data from the URL and display a message like: "yeah, you're still logged in"?
I'm a bit confused atm, so I hope this question doesn't confuse you too.
Let us have we have pages like login.php after_login_page1.php after_login_page2.php
You can follow these simple steps
Set $_SESSION['id'] = $userid //userid from db in login.php
always have session_start() in the successive pages like after_login_page1.php, after_login_page2.php
Check if(! isset($_SESSION['id'])){
header("Location: login.php");
}
at the logout.php page give $_SESSION['id']=''; and do a session_destroy()
The easiest imo is to use a session.
Basically this is PHP automatically setting a cookie (or adding a piece to the url, depending your configuration) on the user system and automatically loading it on each pageview. You can then add data to the session and as long as the cookie didn't expire (or was deleted) and/or you don't destroy the session, you will have that data at your disposal on each pageview the user does.
Take a look here for a small intro to sessions: http://www.htmlgoodies.com/beyond/php/article.php/3472581/PHP-Tutorial-Sessions.htm
Once they have logged in you generally have two options. Store their details or an authentication token (something that will help the PHP on the server know who is who) in a session or store it in a cookie. Both have their perks, but you will need to choose the one that works for you.
If you store data in a session, the user cannot access what you have stored, only your code can. This is helpful if you want to store say, their id or username. You can trust that it would always be their id and username, because they cannot modify it.
With cookies, the user can access and modify them because they are stored on their local machines. Because of this, you need to be a bit more sneaky and hash the users details, then verify who it is with some server-side logic. It's a little more complex.
A session implementation might look like this:
session_start(); //Make sure you call this at the top of EVERY page
if($passwordsMatch){
$_SESSION['user'] = $_POST['username'];
}
//Now we have access to $_SESSION['user'] on every page.
On another unrelated page:
session_start();
print "Welcome, ".$_SESSION['user'];
Easiest way is to "keep users logged in" is to use PHP sessions. When you run session_start();, PHP sets cookie with SESSION_ID in users browser so it can identify this user. After that, you can set any data in $_SESSION array which will be saved in session between page requests.

Categories