Destroy PHP session on page leaving - php

I need to destroy a session when user leave from a particular page. I use session_destroy() on the end of the page but its not feasible for me because my page has pagination. My page is: abc.php?page=1 or abc.php?page=2 or abc.php?page=3.
So, I need to destroy a session when a user leaves from abc.php page. How can I do it without using a cookie?

Doing something when the user navigates away from a page is the wrong approach because you don't know if the user will navigate to a whole different page (say contact.php for the sake of the argument) or he/she will just go to the next page of abc.php and, as Borealid pointed out, you can't do it without JS. Instead, you could simply add a check and see if the user comes from abc.php:
First, in your abc.php file set a unique variable in the $_SESSION array which will act as a mark that the user has been on this page:
$_SESSION['previous'] = basename($_SERVER['PHP_SELF']);
Then, add this on all pages, before any output to check if the user is coming from abc.php:
if (isset($_SESSION['previous'])) {
if (basename($_SERVER['PHP_SELF']) != $_SESSION['previous']) {
session_destroy();
### or alternatively, you can use this for specific variables:
### unset($_SESSION['varname']);
}
}
This way you will destroy the session (or specific variables) only if the user is coming from abc.php and the current page is a different one.
I hope I was able to clearly explain this.

To trigger when the user actually leaves the page, you must use Javascript to send an asynchronous request back to the server. There's no way for the server to magically know the user has "left" a page.
See http://hideit.siteexperts.com/forums/viewConverse.asp?d_id=20684&Sort=0 .

I had a similar issue but mine was on a page reload I wanted variables that I had printed to be destroyed. It was for my login for my web design class I was making error feed back for if user put in a bad username or password. I could get the error to display but if I hit refresh page they errors would just stay there. I found that by just setting the variable to nothing after it printed would kill it. Take a look at what i did:
<p>To access my website please Login:</p>
<form name='login' action="./PHP_html/PHP/login.php" method='post'>
Username: <input type='text' name='username' /><div><?php print $_SESSION['baduser']; $_SESSION['baduser'] = "";?></div><br />
<div style="padding-left: 4px">Password: <input type='password' name='password' /><div><?php print $_SESSION['badpass']; $_SESSION['badpass'] = "";?></div></div>
<input type='submit' value='Login' /> or you can Register
I don't know if this helps at all but it worked for me.
Also, thanks to all you that post on sites like this to help those of us who are still learning.

For a particular page you need to destroy the session, then unset the all session variable
using
unset($_SESSION['varname']);
For the whole site you can use session_destroy();

I solve the problem.First take the current url then chk the page stay on current url.if page is not in the current url then destroy the session.
$url = "http" . ((!empty($_SERVER['HTTPS'])) ? "s" : "") . "://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$page_name="abc.php";
if (!preg_match("/$page_name/",$url))
{
session_destroy();
}
But this code should be used on another pages.Because http is a stateless processes so no way to find when a user leave the page.

You can't tell when a user navigates away from the page, it's simply not possible in any reliable manner.
The best you can do is exploit how cookies work. When starting a session, you're sending a cookie to the client which identifies the client on each subsequent visit, and hence activates the associated session. It is up to the client to send this identification on subsequent visits, and it's up to the client to "forget" his identification.
You can instruct the client to only send the cookie for certain pages, and you can instruct him to forget the cookie when closing the browser (with a lifetime of 0). This can be set using session_set_cookie_params.
Other than that, you can simply ignore the session parameters on pages where they don't matter. You can delete the session (or certain values of it) after some time of inactivity when you assume the client has left.

Borealid deserves credit for pointing to the most elegant solution.
A more kludgey solution is to keep an iframe on the page that is pointed to another "monitor" page which is set to refresh every few seconds. This can be done without JavaScript using:
<meta http-equiv="refresh" content="10">
This refreshes the monitor page every 10 seconds. When this happens, the monitor page can record the time (overwriting the previously recorded time) and session ID on the server somewhere (DB or file).
Then you would have to create a cronjob that checks the file/DB for any sessions that are more than 10~12 seconds old and delete them manually. The session data is usually stored in a directory (specified by your PHP config) in a file named sess_the-session-ID. You could use a PHP function like this:
function delete_session($sessId) {
$sessionPath = session_save_path();
// you'll want to change the directory separator if it's a windows server
$sessFile = "$sessionPath/sess_$sessId";
if (file_exists($sessFile) && unlink($sessFile)) return true;
return false;
}

Related

How to destroy session in PHP when browser back button is clicked?

I have read many related question here but seems not solve my problem. How to destroy session in PHP when user clicked at the browser back button.
Example, current page is home.php, when back button is clicked, it will go to index.php. So should be session will by destroy.
I trying both options. But still not destroy the session.
First Option (home.php)
<?php
session_start();
if (isset($_SESSION)) {
session_destroy();
}
?>
Second Option (index.php) This is not practical.
<script language="javascript" type="text/javascript">
window.history.forward();
</script>
If you want a reliable way to clear all values of any current session you can use this on the loading of any page where you want to remove session data:
<?php
session_start();
if ($criteria_for_session_deletion === true) {
$_SESSION = []; // _SESSION is now an empty array
}
This will remove any value from the superglobal. It will not change the identity of the superglobal, but that shouldn't be important if the variable is now empty.
It is unclear from your question but you may be having overlap issues with browser caching of the outputted HTML page. Please clarify exactly what you're trying to delete?
Clicking on a "back button" is a very problematical way of solving this concept and we really need some clarification from you as to what's actually going on.
If you have a user who needs to have session data removed then you should check this in PHP on a script before any outout is sent to the browser, and then triggering the above code when required.
You maybe should have a "validity check" script included in each page so every time one of these pages is loaded your "check script" is called, and deletes the session data when the deletion criteria is met.
Why do you want to destroy session? That is just irritating. I have seen such implementations in government/bank websites and it pretty much sucks.
Rather you should redirect the user to dashboard if the user is logged in.
This doesn't directly answer OP's question but is a better way.
Something like this:
if (isset($_SESSION)) {
header('Location: <dashboard-page>');
exit;
}

prevent user from accessing previous (restricted) pages after signing out with PHP

When the user decides to sign out, they obviously do so by using a "Sign out" button.
When they do, this script is executed:
if(isset($_POST['submit_Logout'])){
$_SESSION['backend']->logout(); // see this function bellow
unset($_SESSION['user']); // unset only this session since there are other sessions I'd like to keep
session_regenerate_id(true); // makes sure the session id is updated, and the old one is discarded
KD::notice('success',$success_LoggedOut); // adding a notice to another session
KD::redirect('/'); // redirecting the user using header();
session_commit();
}
I'm just unsetting this particular session (user) since there's other sessions that keeps other data available, regardless if the user is logged in or not, to better the user experience.
The logout()-function looks like this - for now:
public function logout(){
$this->accessible=false; // just a flag to check against (see bellow)
$this->username=''; // empty the username
}
Since I'm unsetting the session that holds the related user data, I just realized that this function is probably unnecessary. Alternatively move the unset part etc. into the function..
Anyway, I've come to experience that when a user has logged out, he/she, or somebody else for that matter, has the opportunity to just hit the backwards button in their browser, and voila, they can view the page(s). Of course, if they start clicking on any links, they gets thrown out. But the back-button is still available..
I believe this happens as a result of cached pages/views by the browser. So when they click the back-button, they see a cached page/view stored in the browser memory or something..
Since this page, or view, is loaded into my template trough a index.php page with a permanent <head>, there's not much I can do about the caching of these restricted pages/views. Or is there?
Deleting records from the browsers history is not possible? or preventing these pages from being recorded in the first place?
Point is. What I need to do, i believe, is to force the browser to always request the page from the server. So regardless if the user hits the back-button, or a link to a restricted page, the page should always reqest it from the server, and not the browsers memory..
Or am I not getting this correct?
If so. I do wonder how. How is this usually done?
I have this in my class
private $accessible = false; // when logged in, this is set to true
public function accessible(){
return $this->accessible;
}
At the very top of the page that includes the views into the restricted area I have this:
if($_SESSION['user']->accessible()===true):
Othervise the user is prompted with a login screen.
But that doesn't work as expected. This check is not performed when the user uses the back-button in their browser...
Thanks in advance..
UPDATE
Heres a quick overview of my structure/layout:
/*
when the user is logged in/out, the script that does that is executed up here.
That includes setting the sessions etc. aswell - which means, if the user is not logged in, the access will be set to false.
*/
<head>
</head>
<body>
/*
Here I include different pages with php include;
These pages can be home.pg.php, contact.pg.php, and of course restricted.pg.php
each of these pages includes different content (views as I like to call them) that is presented to the user based on their interaction.
Now. When the user tries to access the restricted.pg.php, I have this at the top:
*/
if($_SESSION['user']->accessible()===true):
/* now each view that is included here should be not accessable if accessable() is not true. */
else:
/* the user is presented with a login form */
endif;
</body>
Did this help?
All the pages that require some to login should have something like this,
session_start();
if(!isset($_SESSION['user']){
//REDIRECT USER TO LOGIN PAGE
}
If its because of the browser caching issue that hitting back is taking you back to cached version of the page (even though user is logged out) then you should redirect the user twice (good practice).
what I mean is create a file called logout.php so when user clicks on logout button,it redirect the user to logout.php (that'll have the session unset code) and after that redirect user to login page.
so current page ----redirects to---> logout.php ----redirects to----> login.php
i think in every page you can just check whether a session is set or not. ex. Session::handlelogin('user')
then you can just make a function namely handlelogin in Session class
Class Session {
function handlelogin($user) {
if (!isset($user)) {
//redirect the user to your login page
}
}
}
Notice: just set this up in top of the page if your using MVC architecture then you can set it up in the Controller
Session::handlelogin('user')

PHP ending sessions(different ways) i dont understand

I'm trying to understand sessions and how some of the functions to end them work.
I've gone to different sites/and even here on SO and, well essentially, nothing is working.
I have an app I'm trying to work on and when the user logs in, I store the username like so
(not going to paste the whole code but you get the idea)
if($row == 1){
session_start();
$_SESSION['usrname'] = $login_usrname;
$_SESSION['usrpass'] = $login_usrpass;
header("Location:index.php");
exit;
}
On the index page of said app I have a check like so
session_start();
if(!isset($_SESSION['usrname']) && !isset($_SESSION['usrpass'])){
header("Location:login-acc.php");
exit;
}
And it lets them in. I check the cookies in firefoxes web dev tools and I see it being generated so I'm going to say "its working" so far.
Now when I want to log out, Long story short I have a logout link that takes them to a page that's supposed to clear all session data and redirect them to the login page. When I'm testing the app and I click the logout link, I get redirected to the login page but when i go back and click the "index page" link. it lets me right in.
In the logout file, trying to FORCE the issue in overkill lol, I have this and nothing seems to work.
unset($_SESSION['usrname']);
unset($_SESSION['usrpass']);
session_unset();
$_SESSION = array();
session_destroy();
setcookie('PHPSESSID', '', time()-3600,'/', '', 0, 0);
header("Location:login-acc.php");
exit;
It redirects me to the login page but again, when I manually go to index page it lets me right in. Or after being redirected to the login page, I hit the "back" button and lets me right in as well.
If I then go into FF Web developer tools app and delete all cookies etc, and navigate to the index page, then it locks me out.
As you can see above ive tried multiple things and in the end, I threw them all together which should do something. My question is since I've put in ALL those functions to try and delete/unset/remove in general the session, what else can I do? I'm a bit lost as to how its supposed to work.
Can someone steer me in the right direction?
You are missing a session_start() at the top of your logout page. It's trying to modify a session that doesn't exist!
You have to start a session in order to end a session. I recommend taking a look at...
http://php.about.com/od/advancedphp/ss/php_sessions_3.htm
// you have to open the session to be able to modify or remove it
session_start();
// to change a variable, just overwrite it
$_SESSION['size']='large';
//you can remove a single variable in the session
unset($_SESSION['shape']);
// or this would remove all the variables in the session, but not the session itself
session_unset();
// this would destroy the session variables
session_destroy();

Force user to logout session PHP

I can't seem to find a straightforward answer to this question. Is there a way in which I can force a logged in user to logout? My login system essentially just relies on a session containing the user's unique ID (which is stored in a mysql database). So essentially just...
if (isset($_SESSION['user_id'])) {
echo "You're logged in!";
} else {
echo "You need to login!";
}
But let's say I want to ban this user, well I can change their status to banned in my database but this won't do anything until the user logs out and attempts to log back in... So, how do I force this user to logout? Preferably without checking every single time they view a page whether or not their status has been switched to "banned" because that seems like unnecessary stress on my server. Any help is appreciated, thank you.
Either you need to check every time they load a page, or possibly look at an Ajax call at set intervals to check their status from the DB.
Then you can use session_destroy(); to end their session. This will destroy their entire session.
Otherwise you can use unset($_SESSION['user_id']); to unset a single session variable
Preferably without checking every single time they view a page whether or not their status has been switched to "banned" because that seems like unnecessary stress on my server.
Loading the user from the database on every page load, rather than storing a copy of the user in the session, is a perfectly reasonable solution. It also prevents the user from getting out of sync with the copy in the database (so that, for instance, you can change a user's properties or permissions without them having to log out and back in).
Try to put this on every page...
if (isset($_SESSION['user_id'])) {
$sql = "SELECT from tbl where status='banned' and user_id=$_SESSION['user_id'] ";
$query = mysql_query($sql);
if(!empty(mysql_num_rows($query))){ // found the banned user
//redirect to logout or
//session_destroy();
}
} else {
echo "You need to login!";
}
if the user is still logged in... check if his/her status is banned or not... if banned.. then logout
You can unset it.
unset($_SESSION['user_id'])
You could use Custom Session Handlers this way you have full control where and how the session data is stored on the server.
So you could store the session data for a particular user in a file called <user_id>.session for example. Then, to logout the user, just delete that file.
Ajax calls in an interval will put extra load on server. If you want real-time response to your actions(e.g. the user will be signed out right when you ban them from your system backend), then you should look into something like Server Push.
The idea is to keep a tunnel open from Server to Browser whenever a user is browsing your website, so that you can communicate with them from server-side too. If you want them to be banned, push a logout request and the process that in your page(i.e. force logout by unsetting session).
This worked for me am using pHP 5.4
include 'connect.php';
session_start();
if(session_destroy())
{
header("Location: login.php");
}
You can use session_save_path() to find the path where PHP saves the session files, and then delete them using unlink().
Once you delete the session file stored in the sever, the client side PHPSESSID cookie will no longer be valid for authentication and the user will be automatically be logger out of your application.
Please be very careful while using this approach, if the path in question turns out to be the global /tmp directory! There's bound to be other processes other than PHP storing temporary data there. If PHP has its own directory set aside for session data it should be fairly safe though.
There is a few ways to do this the best in my opinion based on security is:
NOTE: THIS IS REALLY ROUGH.... I know the syntax is wrong, its just for you to get an idea.
$con = mysql_connect("localhost","sampleuser","samplepass");
if (!$con)
{
$error = "Could not connect to server";
}
mysql_select_db("sampledb", $con);
$result = mysql_query("SELECT * FROM `sampletable` WHERE `username`='".$_SESSION['user_id']."'");
$userdeets = mysql_fetch_array($result);
if($_SESSION['sessionvalue'] != $userdeets['sessionvalue'])
{
session_destroy();
Header('Location: logout.php');
}
else
{
$result2 = mysql_query("UPDATE `sessionvalue` WHERE `username`='".$_SESSION['user_id']."' SET `sessionvalue` = RANDOMVALUE''");
$sesval = mysql_fetch_array($result2);
$_SESSION['sessionvalue'] = $seshval
}
Now I know thats not the very code but in essence what you need to do to be secure and have this ability is:
Everytime a page load check a Session value matches a value in the DB.
Every time a page loads set a new session value based on a random generated DB value. you will need to store the username in a session as well.
if the Session ID's do not match then you destroy the session and redirect them.
if it does match you make the new session ID.
if you want to ban a user you can set their sessionvalue in the DB to a value like "BANNED". this value will not allow them to log in either. this way you can control user through a simple web form and you can also generate list of banned users very easily etc etc. I wish I had more time to explain it I hope this helps.

PHP session issues

I have a mobile script from detectmobilebrowsers.com that will redirect the user to my mobile site however I also wish that when the URL "http://example.com/?mobile=no" is entered a session will be created that won't redirect the user on every page of my site...
$mobile=$_GET['mobile'];
if(isset($_SESSION['mobile'])){
if($_SESSION['mobile']==="no"){
complete();
}
else{
$_SESSION['mobile']="no";
complete();
}
}
elseif($mobile==="no"){
$_SESSION['mobile']="no";
complete();
}
elseif($_SESSION['mobile']!="no"){
checkMobile();
}
function checkMobile(){
// Mobile Detection Code taken out to save space.
gotoMobile();
}
function gotoMobile(){
echo "<script>window.location='http://m.MySite.org/';</script>";
}
function complete(){
return false;
}
Sorry if I seem confusing but in short terms: Mobile Detection (which is set)... make session mobile=no if user does wishes to view full site and when that session is created it is checked on everypage (same php script) and if I set my session for no mobile I want that to stay on everypage... In my case the only thing that happens is the first page is not redirected but when I go to another page it won't display it unless I add the ?mobile=no but the whole point of the sessions here is so this only needs to be done once.
Before you can begin storing user information in your PHP session, you must first start the session:
session_start();
There must be no markup ouputted before session_start(), not even whitespace! (unless output buffering is used).
See http://php.net/manual/en/function.session-start.php.
It sounds simple, but are you sure you are using session_start() at the top of every page before checking all of your session variables?

Categories