Session breaking on form submit - php

Users log in, and a session variable is created from their username. The menus on the site are determined by the users status - admins see an admin menu, coaches see a coaches menu, etc. All that works fine.
Things break down when I need to use the $_SESSION['value'] thing again to pass something from one page to another. For example, a coach will log in and see a list if his games that he has created. To edit the games, he selects one game,a variable is then passed to the next page where he can edit the details of the game he selected on the previous page. the minute the form is submitted on the first page (when he selects the game), its like my session is broken, and I lose all the menus etc.
Other forms on the site that simply add things to the database (users, games, etc) that do not need $_SESSION to pass anything work fine.
Is there something obvious I am overlooking? Is there another method of passing info from one page to another that wont break my session?

This sounds like the so often...
"oh shit, I forgot to call session_start (); before using $_SESSION"
But there are of course many other things that might cause this kinda headache.
check to see that the page your form submits to uses the same (or lower down) sub-domain (if your site uses www everywhere but not there, the cookie holding the session info won't be doing it's job).
check to see that you aren't using https on some parts of your site and http on others
make sure that the TTL (experiation) of the session cookie is long enough so that the user has time to do the edit (this normally isn't a problem, I have yet to come across it with a default configuration)

make sure you have session_start() on all your pages; including the one your form is submitting to

Related

How to clear a session without clearing other parts of the site

Difficult to explain this but here goes. I found a similar question in the search but it was for C, not PHP.
I am developing a PHP site which has two logged-in sections, one for employees and one for employers. When either user logs out, their session is cleared, at the moment with "session_destroy()". I also use that at the login page to clear any previous session.
The problem comes if I am working on both sections at the same time. Because they are on the same "site", logging into one logs out of the other. I am forced to use two browsers at a time, one logged into one section and the other into the other.
Is there a better way to end a session when a user logs out rather than "session_destroy()", something that won't affect the other part of the site?
you can save each site's session data in a different part of the session:
$_SESSION['site1'] = ... ;
$_SESSION['site2'] = ... ;
and then call unset on the session you don't want any more:
unset($_SESSION['site1']);
you unset a specific session
unset($_SESSION['variable']);
variable will be the user/admin session value

PHP session overlapping for two customers

Have a session problem with application when opened in multiple tabs of a browser.
In my project a user can have multiple log in id's so he could log into the app with two id's
at the same time as two diferent users. but when they try to log in with two id in multiple
tabs of a browser. the same session of the browser is being shared and the data gets messed up.
Any insights to solve this issue?
I see a pattern in mail.yahoo.com , if i log into my mail.yahoo with one user id and try to login in
to other user id in the new tab. one of them logs out. Any idea how this could be done...
Thanks
Piecing this together from against other answers it sounds like you need multiple application streams.
That is, you have a situation where you need multiple "users" to be logged in to the application on different tabs on the same browser, same machine.
This isn't because they are different people using the machine, but rather the same person working with different personas.
It turns out, I've implemented something similar in the past myself, in order for managers to be able to "ghost" through a system as their staff members. They log in as the other user, but in a read only mode so they can see what's going on.
OK. So how to do it.
Put simply - the session isn't enough - you need more than that. The session ID is stored in a cookie on the client machine and there isn't really much you can do about the set-up - one browser = one session.
However, what you can do is split that session up with an application stream, or application context.
That is, don't store anything in the root of your session - split your session into distinct components into which you have a set-up identical to your current session.
The key for each session is then the "application stream" key. You need to pass this around in your URLs.
E.g.
Your current session may have a simple set-up:
$_SESSION['user'] = 'some username';
$_SESSION['role'] = 'power user';
Instead you store that as:
$_SESSION[0]['user'] = 'some username';
$_SESSION[0]['role'] = 'power user';
On all urls you add:
&appId=0
And whenever you reference your session you use something like:
$username = $_SESSION[ $_GET['appId'] ]['user'];
Obviously, you wrap all this up in a nice session handling class, but that's the basic idea.
If you want a link that generates a new login page with a new application stream, you simply change the appId on the link (or completely omit it and trap that in your login code).
E.g.
$sLoginLink = "<a href='/login.php?appId=" . generateNewAppStreamId() . "' target='_BLANK'>New Login Screen</a>";
As everything is still stored in the session, the whole of your application should work exactly the same - just as long as you always have the appId on every URL in the system.
I've tried to make the explanation as simple as possible - forgive me if I've used too many words.
If you want to use session then you must arrange such mechanism that only one user can be logged in same browser. At login page, check availability of session and it is already have a value than redirect your page to any logged in page like home, profile or whatever you have.
When the user logs out or logs in using a different user ID you must use session_regenerate_id() to force PHP use a different cookie for the new login.
This is actually the best practice on logout.
If you want to have two users logged in simultaneously from the same browser you have to put something in the URL to tell them apart. For example, after login, user #1 will see all the pages as http://www.example.org/1/... and user #2 will have its own customized URL (http://www.example.org/2/...). Then you need to use session_set_cookie_params() for each user with the correct value for parameter $path ('/1' for user #1, '/2' for user #2 and so on).
It's not recommended to use the user ID as customized user directory but to generate a hash from it.

What's the easiest way to keep tracking a visitor through multiple pages?

I have users coming from both organic and paid search.
organic users land on page.php, paid users land on page.php?source=paid.
A PHP variable on page.php would change according the source string, to help me identify where the user initially came from, for example, if he purchase something on my site right from the same page, I would have an indication.
The problem:
I have multiple pages in my website. once a paid user decides to navigate to another page such as page2.php, the indicating variable won't work, as he navigated to page2.php, and not to page2.php?source=paid.
So one possible messy solution, would be to drag the string all over the website, by placing on every link, an IF/ELSE that would insert at the end of all the href in the page, a ?source=paid string, in any case that the user initially landed with the ?source=paid string.
But, is there another option? I suppose there's a way to do this with cookies? but I have never dealt with cookies, and rather not to, unless it's easy.
Thanks
This is exactly what sessions are for:
Sessions are a simple way to store data for individual users against a unique session ID. This can be used to persist state information between page requests. Session IDs are normally sent to the browser via session cookies and the ID is used to retrieve existing session data.
To solve this I would recommend you to use Sessions.
On the first page you need to set the session variable with something like this:
<?php>
session_start();
if isset($_GET['source']) {$_SESSION['source'] = $_GET['source'];}
and the rest of your first page goes here..
?>
On the other pages you can recall the sessionvariable like this:
<?php>
session_start();
if ($_SESSION['source'] == 'paid')
{ paid version}
else
{unpaid version}
?>

Populate form in iframe of external website

I am trying to write a php page that will load several different websites in different iframes. Several of those sites will need the user to login. What I need to do is basically allow the user to only type in the username and password once and then populate all the other forms (that are basically using the same user-pass pair for logging in)
Now i know that since those are external sites you don't have access to the DOM and XSS is not allowed and all, but i was wondering if theres actually any other way to achieve that.
Somebody actually suggested me to simulate keypresses and have a javascript that will basically go from field to field and essentially type in the username and pass but after doing some research I dont think thats possible since you can only simulate the event and not the actual keypress so...any other suggestions?
NOTE: I have also checked this but agreeing with the other sites/domains is not an option in my case!
Thanks -- Mike
that depends.
if those sites share a domain (the parent window and iframes), then it's possible for the top window to communicate with the child iframes. AJAX prevents cross domain (that includes inter subdomains) but iframes can communicate as long as they belong to the same top domain.
see https://stackoverflow.com/a/9338955/575527 and https://stackoverflow.com/a/9676156/575527
a better approach is to have a "top domain cookie" where that cookie is visible in all those iframes (assuming they are of the same top domain). login once using a single login page, then subsequent requests in the pages will need to check the cookie vs the session if that user is logged in.
or if those pages have different domains but access the same database, then one can just then pass the session id as a url parameter to the iframes rather than as cookies. then the website in the iframes will parse the session id and check in the database if those sessions are valid, are current, and are logged in.
all of which need additional CSRF and XSS checking as session IDs are in the open.
You cannot do what you describe in JavaScript.
However, depending on what you need to do with the data/websites once the user is logged in, you may be able to use a remote POST to simulate that behavior. See this question for more info.

What is the best way to deal with sessions when the user may stay logged in, but a session key needs to be updated, because of another update?

I'm working a site where users could technically stay logged in forever, as long as they never close their browser (and therefore never get a new session key). Here's what I could see happening: a user leaves a browser open on computer A. The then use computer B, login and change their name which is stored in the session. They logout of B, but A is still logged in and still has their old name stored in the session. Therefore, their name won't be updated till the next time they logout manually or they close their browser and open it again and are logged in through the remember me function.
Name is a simple example, but in my case the subscription level of their account is stored in the session and can be changed.
How do you deal with this?
A few ideas that I have are:
After a period of 10 minutes or more, the session data get's reloaded. It might be exactly 10 minutes if the user is highly active as the function will get triggered right at the 10 minute point or it could be after 2 hours if the user leaves and comes back and then triggers the functionality.
Store as little information as possible in the session and load the rest from the DB on every page call. (I really don't like this idea.)
Use database sessions and use the same session on all the computers. I like this, but I could see it getting confusing when something like search criteria are stored in the session--the same criteria would show up on both browsers/comptuers.
For information, even such as the user's name or username/email address, store it in the session, but for other information that would heavily affect their abilities on the site, don't store it in the session and load when needed (attempt to only do it once per instance).
Are there other better methods?
--
Another option: 5. Use database session and when an update is made load the user's other sessions (just unserialize), change the relevant information and save them back to the database.
I would go either with number 1 or number 4. If you store the time of the last update of the information, you could even ask on every request whether the date has been updated.
Don't store information likely to change in the session, if you're looking at scenarios like the one you outline. Just get over your dislike of loading user data with every page - it's by far the best idea.
I'm guessing you don't want to load the data from the database because you're concerned about performance issues somehow. Before you try out any of the other solutions, you might want to test how long it takes to actually load a users data from the database, then check that against your number of users - chances are you won't see any performance problems due to loading user profiles on every page.
Regards
I'd go with option 6: only store userid and session specific stuff (search criteria) in his session and put the rest into APC/xcache (memcached if you're using multiple servers).
this way you'll only have to go to the database the first time (and after the cache expires) and you can still share any data between users sessions.
Normally you should do 2), but you don't like it.
maybe you can use sessions stored in db.
when a user change his name, put into all sessions from that user the information "refresh userdata".
on the next request the userdata is reloaded again into the session and is cached there.
this can be done be reusing your loaduserdata function which called at login.
php session_set_save_handler() - also read comments
php session_decode() - to read the username from the session to store it additionally to the sessiondata. usefull for easily to find the users sessions for updating.
[edit]
don't forget:
when you are updating all the sessions while the page is generated (between session_start and session_write_close) you changes maybe lost.

Categories