I would like to know if calling via AJAX or jQuery or whatever the server side, can I clean a session var??
Nowdays I have a FB application that runs with PHP and it's behaviour depends on a PHP session vars, and I would like to clean that session vars on the HTML event unload in the case that the user returns before the lifetime of those vars has passed.
Can it be done??
Presumably, because you are storing this information in session variables, you want it to persist between pages. Therefore, wouldn't clearing this information every time the user leaves a page defeat the purpose?
If you are referring to your PHP app in an iframe, and only clearing it when the user navigates away from the parent frame, I don't believe this can be done, if the parent frame is 'owned' by a different domain.
Yes, but for the static components on the calling page dependent upon session data will not be cleaned due to the stateless nature of the web. It would require a page refresh of some kind.
For example, if I clicked logout button that send an AJAX call to clear my session. I would technically still be logged into the originating page until I refreshed.
Related
I'm in the process of building a single sign-on system and I am using cURL to send a request off to a file on the main site and return the results / their user data; however, if the user logs into the secondary site via a cookie (ie; they aren't currently logged into the main site) I need to make sure they get logged into the main site at the same time and set some session variables so that they don't continuously have to keep logging in via a cookie on the secondary site.
Obviously we normally would end up with a different session id on the file I am calling via cURL and hence setting any $_SESSION variables there wouldn't be available to the secondary site; so I tried passing the session_id from the secondary site with the call via cURL and then in that file I did this to set the session id so that any $_SESSION variables I set there would then be available to the secondary site.
// Get session ID
$sid = trim($_GET['session_id']);
// Set the session id so we can get the added session data below via the forum
session_id($sid);
session_start();
However when I do that and try and access the secondary site the page won't load, it just hangs - I tried removing that code and loading it again but it won't load until I restart Apache.
Btw.. if it matters, this is on my local dev machine, which is Windows XP Pro.
Any ideas!?
I’m assuming here that both your main and your secondary site are on the same server and use the same session settings, especially the same session.save_path, is that correct?
If so, that’s where your problem lies:
The default session handling mechanism of PHP works using files to save the session data.
And to avoid concurrent write access to the session file, the file gets locked as long as one script (one script instance would be more exact) is still working with the session. Every other script that wants to access that particular session has to “wait”, until the first one is finished using the session.
So with you trying on your secondary site to start your session with the session id already in use on your main site, the script on your secondary site can’t access the session because of that locking.
And since your main site’s cURL request is waiting for the secondary script to finish, which is itself still waiting for access to the session … you’ve got yourself a nice deadlock here :-)
What you can do, is call session_write_close in your main site script before making your cURL request – at that point all data is written to the session file, and the file lock is released.
You have to be aware though, that you can not use the session again in your main site script instance after that – well, you can still read data from and push data into the $_SESSION array, but since the session is already closed, all data that you alter in that array after that point will not be persisted any more. So do what you have to do with the session in your main script, then close the session – and then make your cURL request.
Edit: Well, come to think about it – not sure if the above actually helps here … because your whole approach might be flawed already. Calling a script via cURL on your secondary site will not actually set a session cookie for your secondary domain in the user’s browser – because every response of that secondary site’s script does not “land” in the browser, it lands in your main site script, because that’s where you doing the request from.
I think what you really need here, is to call a script from your secondary site in the user’s browser (JavaScript/AJAX request, iframe, embedded image), so that it’ll set a cookie with the session name and session id as value under your secondary site’s domain – only that will make PHP able to “recognize” the user’s browser once they navigate to your secondary site. Actually opening the session will not be necessary (still assuming that both sites use the same session), because the session is already started, and all it needs for PHP to pick it up on the secondary site is a matching session id from the cookie.
So try doing that instead – but be aware of the problems you might run into with that, since the browser will consider the cookie for the secondary domain as a third party cookie when you are trying to set it in the context of your main site (and the domains don’t match, e.g. one is not running on a subdomain of the other or something like that).
Situation:
I have a Javascript/jQuery web app which communicates with a PHP/MySQL/Zend Framework 1.12 backend. The web app runs inside an iFrame (loaded with jQuery fancybox in iframe mode).
The application creates an object on the backend and saves the current session ID with it. It then displays the object's properties on the front end and modifies the object on the backend through ajax calls when the user interacts with the application. The session ID is used to check if ajax requests are coming from the same user (user is not logged in so it's the only way to check).
I use jQuery to do the ajax calls and Zend_Session to work with sessions in PHP/Zend.
Problem:
Now, the problem is that in safari 6, these ajax requests have a different session ID so they don't match the session id stored in the backend model object and access is denied.
This does only happen when running in an iframe, not on any other browsers, not on other versions of safari (5 or below)
Does anyone have an idea what can cause this and how to deal with it?
Some more info:
The entire application runs in the iframe, the call from which the session id is stored in the backend model as well. So I'd think all these calls have the same session id.
Another thing: once I run the application in a separate tab, and then in the iframe again, the issue disappears: from then on until I kill the browser session I get the same session id every time as I would expect. That smells like a bug to me, frankly.
The key issue is the iFrame. As a part of the Safari security model, requests running in iFrames are treated separately from the rest of the page requests. It's part of their 3rd party cookie protections. As I understand it, Firefox22 is going to start doing the same sort of thing, but not quite as restrictively.
If you're sure you really want to get around this, pull PHP's Session Id cookie out and put it on the query string for the request to the iFrame. You can then pull the session id from the query string and use that one. (You won't end up with one in the cookie data if you do this.)
If I have for example 7 open tabs with user personal profile i browser, after session is going down user sees the alert confirmation does he wan't to continue his session or not, if not, session destroes and all 7 tabs with his personal profile should be loaded end php redirect them to login form.
here is the question, how can I determine that the session were destroed and we should reload tabs? Ajax is not good solution coz it's make a lot of queries to server
I think AJAX would be the solution, there's no need to make a lot of queries. Just use a javascript callback function which is executed once each 5 minuts and checks if user has chosen to not continue his session. If yes, then redirect...
If you do not wish to use AJAX, which is the only available solution I know of for dynamic refresh/closing capabilities, you will have to check if the session exists each time the page is loaded to determine if the page should be reloaded or closed. You can do this by saving the session id in a cookie and comparing it each time the page is loaded. This will tell you if the session has ended and can allow you to reload it if I recall correctly.
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?
If I had a user logged onto my site, having his id stored in $_SESSION, and from his browser he clicked a 'Save' button which would make an AJAX request to the server. Will his $_SESSION and cookies be retained in this request, and can I safely rely on the id being present in the $_SESSION?
The answer is yes:
Sessions are maintained server-side. As far as the server is concerned, there is no difference between an AJAX request and a regular page request. They are both HTTP requests, and they both contain cookie information in the header in the same way.
From the client side, the same cookies will always be sent to the server whether it's a regular request or an AJAX request. The Javascript code does not need to do anything special or even to be aware of this happening, it just works the same as it does with regular requests.
If the PHP file the AJAX requests has a session_start() the session info will be retained. (baring the requests are within the same domain)
What you're really getting at is: are cookies sent to with the AJAX request? Assuming the AJAX request is to the same domain (or within the domain constraints of the cookie), the answer is yes. So AJAX requests back to the same server do retain the same session info (assuming the called scripts issue a session_start() as per any other PHP script wanting access to session information).
Well, not always. Using cookies, you are good. But the "can I safely rely on the id being present" urged me to extend the discussion with an important point (mostly for reference, as the visitor count of this page seems quite high).
PHP can be configured to maintain sessions by URL-rewriting, instead of cookies. (How it's good or bad (<-- see e.g. the topmost comment there) is a separate question, let's now stick to the current one, with just one side-note: the most prominent issue with URL-based sessions -- the blatant visibility of the naked session ID -- is not an issue with internal Ajax calls; but then, if it's turned on for Ajax, it's turned on for the rest of the site, too, so there...)
In case of URL-rewriting (cookieless) sessions, Ajax calls must take care of it themselves that their request URLs are properly crafted. (Or you can roll your own custom solution. You can even resort to maintaining sessions on the client side, in less demanding cases.) The point is the explicit care needed for session continuity, if not using cookies:
If the Ajax calls just extract URLs verbatim from the HTML (as received from PHP), that should be OK, as they are already cooked (umm, cookified).
If they need to assemble request URIs themselves, the session ID needs to be added to the URL manually. (Check here, or the page sources generated by PHP (with URL-rewriting on) to see how to do it.)
From OWASP.org:
Effectively, the web application can use both mechanisms, cookies or
URL parameters, or even switch from one to the other (automatic URL
rewriting) if certain conditions are met (for example, the existence
of web clients without cookies support or when cookies are not
accepted due to user privacy concerns).
From a Ruby-forum post:
When using php with cookies, the session ID will automatically be sent in the request headers even for Ajax XMLHttpRequests. If you
use or allow URL-based php sessions, you'll have to add the session id
to every Ajax request url.
It is very important that AJAX requests retain session. The easiest example is when you try to do an AJAX request for the admin panel, let's say. Of course that you will protect the page that you make the request to, not to accessible by others who don't have the session you get after administrator login.
Makes sense?
One thing to watch out for though, particularly if you are using a framework, is to check if the application is regenerating session ids between requests - anything that depends explicitly on the session id will run into problems, although obviously the rest of the data in the session will unaffected.
If the application is regenerating session ids like this then you can end up with a situation where an ajax request in effect invalidates / replaces the session id in the requesting page.
That's what frameworks do, e.g. if you initialize session in Front Controller or boostrap script, you won't have to care about it's initalization either for page controllers or ajax controllers. PHP frameworks are not a panacea, but they do so many useful things like this!
put your session() auth in all server side pages accepting an ajax request:
if(require_once("auth.php")) {
//run json code
}
// do nothing otherwise
that's about the only way I've ever done it.