159

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?

Click Upvote
  • 235,452
  • 251
  • 553
  • 736

8 Answers8

196

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.

thomasrutter
  • 104,920
  • 24
  • 137
  • 160
  • 10
    Followup: the server can set an `HttpOnly` flag when setting a cookie which means that your Javascript won't be able to see the cookie. However the cookie *will* still be sent for both AJAX and regular page requests and continue to work exactly the same. Your Javascript just won't see it in `document.cookie`. – thomasrutter Sep 11 '13 at 00:47
  • If PHP error reporting is turned on, you can get a session error returned with the AJAX response. I've been intermittently getting a `Warning: session_write_close(): Failed to write session data (user)` error lately in a project, but only when the AJAX request happens during the loading of the rest of the page. I'm using a MySQL DB for the session data, and it's possible that the main page request is locking that table, preventing the AJAX request from accessing it. – Buttle Butkus Aug 07 '19 at 03:57
  • @ButtleButkus that sounds like a problem in your server side code and I'm sure people will be willing to help if you submit that as its own question. You shouldn't be getting that error just because you're using MySQL for sessions as it shouldn't lock in a way that would fail with an error. It may be an issue with MySQL connections being saturated, or some other unrelated issue. – thomasrutter Aug 08 '19 at 03:26
  • It’s happening on a vagrant machine so the MySQL connections should be saturated. I’ll definitely post a question if I can’t figure it out soon. – Buttle Butkus Aug 08 '19 at 05:04
23

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)

Ólafur Waage
  • 64,767
  • 17
  • 135
  • 193
23

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

cletus
  • 578,732
  • 155
  • 890
  • 933
  • 1
    I might be wrong, but I thought it wasn't even possible to post ajax requests to other domains (subdomains excluded)? – Emil H Mar 24 '09 at 10:51
  • You might be able to cheat with the dynamic script trick. Never tired it though. – cletus Mar 24 '09 at 10:55
  • 1
    Yes, ajax requests can't be made to other domains. However you can dynamically insert a – Click Upvote Mar 24 '09 at 13:07
  • 1
    ajax requests can't be made to other domains. but you could make a proxy in your php code. ajax request to the proxy, the proxy request to other domain. – Peter Long May 15 '11 at 03:38
  • 2
    Just a note... ajax requests can be made cross-domain, but only if the response type is jsonp. I do this all the time. – Epiphany Dec 03 '12 at 16:19
  • @Epiphany JSONP is a technique that uses dynamically inserted – thomasrutter Sep 30 '13 at 03:25
  • I must have missed something in previous comments: I sometimes have to do some crossdomain ajax requests, and a simple header serverside allows them: (Note: previous comments were written years ago, maybe things changed in the while?) – fpierrat Jun 03 '15 at 23:11
  • Note that it's now several years later and secure and reliable cross-domain AJAX is now a reality thanks to CORS and the `Access-Control-Allow-Origin:` header. – thomasrutter Jan 31 '17 at 05:12
  • even if ajax requests can't be called off-domain someone could always write a php code to get the ajax file anyway... or one of the many other methods to retrieve the contents of a php file. I'm looking at this as I've got a customer who wants to hide their audio files from downloading and I'm thinking of encoding the audio url, adding some salt, and passing it to an ajax file, check if session variable is set right, if it is return audio url, else tell the site to get lost. – TheKLF99 Jul 08 '20 at 07:00
8

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:

  1. 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).

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

Community
  • 1
  • 1
Sz.
  • 2,486
  • 27
  • 32
  • Any reliable statistics on how many people has _session_ cookies disabled? (I failed to find any. Only on Javascript: that seems around 2% in US/Europe and ~1.2% world avg.) – Sz. Jun 02 '13 at 00:43
  • Session IDs on the URL is an outdated, [insecure](http://security.stackexchange.com/questions/14093/why-is-passing-the-session-id-as-url-parameter-insecure) practice. On today's web, nobody should assume they can surf with cookies disabled and still log in to web sites where they hold an account. If one of your visitors has cookies disabled, it's probably safe to assume that either a) they specifically do not want to be able to sign in on any site for privacy reasons; or b) they did it accidentally, and now they can't log in to *any* site, not just yours. – thomasrutter Sep 30 '13 at 03:36
3

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?

Bogdan Constantinescu
  • 5,196
  • 4
  • 37
  • 50
0

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!

AlexA
  • 3,838
  • 8
  • 47
  • 83
0

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.

0

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.

John
  • 426
  • 5
  • 15