Is it important to change session on each page request? - php

It causes conflicts when the user open another page on another window/tab. So how to prevent these conflicts? One way is to set session same for each page the same..every time the user logout/logins the session will be regenerated.
<?php
//every page sets its own session if its not ajax so that it dont expire
if(is_ajax()){
$_SESSION['token'] = md5(rand());
}
echo '<div id="token">'.$_SESSION['token'].'</div>';
?>
tokens will be passed from div.token to perform ajax requests by jquery. but then when the user opens another tab new session is set then the other page returns 'Invalid Request' error.

Having multiple pages or tabs open should not interfere with the session. If it does, you're probably putting a bit too much into the session.
What are you storing in the session? It sounds like you're probably storing something in the session that belongs in the URL.
Edit: After seeing your edit, you may want to check out the top answer in this question:
PHP - CSRF - How to make it works in all tabs?

Related

EMPTY SESSION MANY TIMES PHP

I make this post because I am really confused about session in PHP. I have a page (index.php) and I save in session a lot of variables (for example, one of this is $_SESSION["FID"]) and i redirect the user in a third party iframe. When the user enter successful his data in iframe, the iframe redirects the user again in index.php and also saves in session other variables.
When the user enters again in index.php I check the session, which comes from iframe (every time the session is set) and after that I make a check if $_SESSION["FID"] isset.
The problem is that most of the times (regardless the browser or something else), $_SESSION["FID"] is empty. Why is this happening? How can I find a solution in this?
I 've tried to be clear and not to confuse you.
You must put session_start(); at the top of every page you want you $_SESSION data to exist.

Prevent back button after logout

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.
}

PHP + Logout Member when Session Expires

I've a site where people login and a SESSION is created.
I have noticed that if you leave the site for long enough (not sure exact time frame) the session ends but the members is still in the site. They can still click and navigate around and I believe this has resulted in some meaningless data in the DB as SESSION variables like userID don't exist.
I was looking for advice around logging users out when the SESSION ends.
I have looked at code like this - any better ideas?
<?php if(!isset($_SESSION[]) {header(loginpage.php);}?>
Is there a better way to write the above code?
Where should this code be placed? Just on the navigation menu or really on any place a user can click?
Finally is there a way to understand when the SESSION naturally expires - is there a SESSION variable I can print to screen to see the timeleft etc?
thanks
You need to validate the session, you already headed into that direction with your code, but it's not enough:
<?php if(!isset($_SESSION[]) {header(loginpage.php);}?>
It's not enough because $_SESSION[] exists automatically after the session is started (the session mechanism in PHP, see session_start).
Instead, if you have saved the userID inside the session, check that one:
isset($_SESSION['userID'])
If the session really expired, it should not be set.
I agree with the above answer. I would say it depends on how your application is architected to say where this belongs. before there is any output to the screen I am assuming your calling session_start, then immediately check for a session variable such as userID that gets set after a user logs in. if it's not set redirect setting a header for location to your login page. you could also write some js that checks the session cookie for a value at a specified interval(I believe, it's been a while so test it out), then when the variable isn't present you can redirect to the login page. a third way would be for the js code to make an XHR call to a php script to check out the session for you.

How can I reset session when user navigates away from page?

I've created a session to keep track of some user actions on a specific page.
When user navigates away from that specific page (but still on the same site), I need to reset the session.
I can set set timer for when session expires, but that's not what I want.
How can I reset session on page navigation?
Just make resetting the session the very first thing you do when loading a new page.
Do you have a single page that all traffic is routed through? If so you could do a simple check
if ($current_page != $session_page) {
$_SESSION = array();
}
If you don't have a single page all traffic goes through, then you will need to reset the session at the beginning of every other page.
$_SESSION = array();
Alternatively you can use
unset($_SESSION);
or
session_destroy();
Though note these handle slightly differently to the suggestions above. Note the second (session_destroy) will require you restart the session should you need it again.
You can never be sure that the session is really destroyed.
But there is an old trick used in for example chat applications where a "... is leaving" message is to be printed: On unload just open a popup windows with window.open() that calls your logout page and then closes itself.
What I've done in the past is make a quick ajax call on unload to an unset page, much like the other answers on this page.
<script>
function myAjaxCall(){
//if using jquery
$.ajax('unset.php');
}
</script>
<body onunload="myAjaxCall()">

Incorrectly redirecting user back to a PHP page after submitting a form

All,
This question probably has a very simple answer - something I'm overlooking. But maybe someone can tell me where to look...
I have a PHP page ("index.php") with a very simple login form (e.g., username and password).
When the user clicks the "Submit" button, the form POSTs the values to another PHP page ("login.php"). That page is supposed to confirm the user's credentials, then do the following:
If the user's credentials are not
correct, redirect the user to
error.php, along with an error
message
If the user's credentials ARE
correct, create a session and set $_SESSION['authenticated'] = true, then redirect him to "loggedin.php"
[UPDATE]
Then, on loggedin.php, I check to see that isset($_SESSION['authenticated']) returns true. If it does, then proceed. If not, redirect the user back to index.php.
However, here's what happens. The FIRST time I fill out the form (with valid creds) and submit it, I can see briefly in the URL bar that the user is sent to login.php, then loggedin.php, but then BACK to index.php.
But, if I re-enter the same credentials and submit the info a SECOND time, everything works exactly as it should.
So, in short, it looks like either login.php is not setting the $_SESSION variable the first time through, or that it is, but for some reason, it's not set when I check it for the first time on loggedin.php
Is there some delay between setting the variable on login.php, and having isset() return true on loggedin.php?
Or, is there something else I'm doing wrong?
Here are the relevant (I think) snippets of code:
In login.php:
session_start();
$_SESSION['authenticated'] = true;
header('Location: http://www.mydomain.com/loggedin.php');
In loggedin.php:
session_start();
$authenticated = $_SESSION['authenticated'];
if (!isset($authenticated)) {
header('Location: http://www.footballpoolz.com/mobile/index.php');
die();
}
Many thanks in advance for any advice or insights!
Cheers,
Matt Stuehler
I think I may know the cause of the error. The session has to be linked to the browser and the IP address (this way more than one person can be logged in at a time). This means that the session has to not only be stored server-side, but the client has to have a link to the session as well so you know who they are logged in as when they request data. This session id is shared as part of the header during all HTTP requests.
When you're redirecting the user, though, you aren't giving them a chance to send new headers, are you? You're probably just sending them the new page. This new page never saw a header from them, so it doesn't know which session variable (PHP has hundreds or even thousands of session variables) belongs to them. When you log back in a second time, you are sending a header, and thus you're sending the session ID and PHP knows which session variable is yours.
There are two solutions. The first is to find a way to redirect them that forces them to send a new header. I believe using header("Location: www.mysite.com/newpage.php"); will do this. I may be mistaken.
The alternative is to temporarily pass the session id when you redirect them to loggedin.php so that you know they are logged in for that first page load. After the initial page load, you no longer need to take this extra step since it will be done for you every time they request a page. To pass the session id you just append ?SID=... to your redirect.
http://www.php.net/manual/en/session.idpassing.php
Redirects really slow things down and cause extra server load. What you should be doing is posting back to the index.php page, which will detect if there is a POST or not. Then log the user in and display the contents of the loggedin.php file. No redirects necessary.
After all, you already know that the user is validated, why redirect them to another page where you have to check validation again (which you just did)? This is more of the concept of a "Front Controller" where your index.php acts as a router to load and display different pages. Even if it's just a welcome page when they login. This eliminates any issues with delays.
You are doing a session_start, right?
Instead of using this true . Try to put some value.
like $_SESSION['username']='mattstuehler'
and check
$loggeduser=$_SESSION['username'];
if(!empty($loggeduser))
I dont see any bugs anyway

Categories