The more I read about sessions, the more confused I get.
But maybe I should ask this first...
Does Drupal 7 have a "default" session? (One that is established when a user first visits a site.) Or, are sessions only explicitly created by a module?
Background for question: An anonymous user might put "stuff" into a shopping cart, and then on check-out authenticate as an existing user. Will the newly created user session have access to the original anonymous session (and shopping cart). The shopping cart is implemented using session and user IDs (but it seems as if each anonymous user gets the same session ID).
Or will drupal_session_regenerate copy the old (anonymous) session into the new session?

Comments
Inherently, Drupal does not
Inherently, Drupal does not automatically move things from anonymous ("default" session state if you will) to a users authenticated ("logged in" session state) session. Drupal is a fair bit more bare bones than that under the hood.
Drupal does have the capability to do this though, should you write the code to do so... and many modules DO infact do this for you!
In your specific case... Drupal Commerce carries the anonymous session over to your new session as an authenticated user. They accomplished this in the Drupal 7.x-1.x module about 3-4 years ago (see: https://www.drupal.org/node/797554)
So when you make a bunch of anonymous comments, and then register, those aren't automatically ported over to your new user account... unless you code up a crafty way of doing so.
Jesse Nicola -- Shredical six different ways to Sunday! -- My Portfolio
Thanks for the Drupal
Thanks for the Drupal Commerce link, Jesse!
However, my issue is a bit more generic (sorry for the poor phrasing above). How can I tell if Drupal is giving each new visitor to the site a new session?
As far as I can tell, session_name() returns the same ID for all anonymous users.
Are you sure using
Are you sure using session_name() is sensible? I personally would delve into session_id() per http://php.net/manual/en/function.session-id.php to see if you're getting unique session between anonymous users. I'd be VERY surprised if you weren't!
I've very rarely had to investigate the inner workings of Drupal for how it specifically interacts with $_SESSION, so I'm admittedly not an expert on this topic, however I'd be surprised if it did anything different, to the point I'd wager a calzone on the outcome being as I've written.
Report back on how session_id() treats you. I may just owe you a calzone :)
Jesse Nicola -- Shredical six different ways to Sunday! -- My Portfolio
I'm not sure about anything
I'm not sure about anything regarding sessions!
I think D6 used session_name, but that now appears to be an "internal" function in D7. And I can't find much (coherent) information on how drupal 7 core handles sessions. Just http://api.drupal.org/api/drupal/includes!session.inc/7
I've give session_id() a whirl and see what happens!
Thanks!
Ah Ha! You get to treat
Ah Ha! You get to treat yourself to a calzone because you were right!
session_id() is the correct function to use, not session_name()!
I'm actually going to get one
I'm actually going to get one meow, hah!
I'm only partially correct per comments below. The major takeaway being that a session isn't inherently initialized for anonymous users visiting, unless some one starts a session in their contributed/custom module. It's a takeaway from pressflow, which I completely didn't even think about. I forgot about the pressflow days :)
Jesse Nicola -- Shredical six different ways to Sunday! -- My Portfolio
Well, don't eat it all!
Well, don't eat it all! :-)
I'm still investigating, but session_id seems to be returning a session ID, just not the one I'm using! The result is a bunch of different shopping carts.
And the session info in $_COOKIE is all different too.
And it doesn't seem to matter how often I call (or don't call) drupal_session_start() I always get the same session.
why is the id important?
I'm curious why you need the id of the session at all? I'm pretty sure that simply writing to $_SESSION will allow php to keep each users session straight. the more you call the session instantiating functions the more confusing things will get. I'd recommend simply working with just the super global.
put another way, my recommendation is to store the cart information in $_SESSION & allow drupal to store it. don't try to store the cart data in your own tables - it'll make cleanup way too difficult. (I'm guessing you are trying to create a foreign key in a cart table to the session table; that won't work well)
Also, if I remember right, the "flag" module is one of those modules that creates a session for each anonymous user that uses it. Unless they fixed that (its been several years since this was raised as an issue) it might serve as a useful example for your needs.
The session id is used to
The session id is used to determine which items in the cart belong to which users - some of which are anonymous, and some are logged in. Those items for logged in users are stored with a session id of 0 and with a non-zero uid; items for anonymous users are stored with a non-zero session id and a zero uid.
We don't want to keep cart items in $_SESSION because the lifetime of the cart could outlast the lifetime of the session (like when the browser/client computer crashes).
I'm not sure that logic lines
I'm not sure that logic lines up. Under normal conditions, when the user's session expires, you are going to lose the session (including the id), which will break the alignment with whats in the cart. That'll happen wether you store the data in $_SESSION or if you store it outside of $_SESSION and relate it to $_SESSION['id'] (thats not a real value, just a representation of my point)
If you want to work around this, You are probably much better off adjusting the cookie assignment of sessions to be extremely long lived, then using one of the session timeout modules to deal with sessions that exceed a certain length of time.
There area couple of benefits to this:
1) That will keep users carts in tact forever
2) if a users browser crashes, they won't lose their cart
3) when anon-users log in, their session gets destroyed and recreated by Drupal (a security feature) the data in the session is preserved and copied when this happens, so the cart would be preserved even though the id changed - that won't happen if you just relate the session id to a cart item in a table
4) It'll help you give the amazon feel of "welcome back xxx, to do anything, you need to log in" without storing their name in a cookie.
A really important thing to re-highlight is #3: Drupal regularly destroys and reissues session values for a couple of reasons; the most important of which is security during the login process. Relying on the sessionid to do anything data related is really not recommended because of this. Its unlikely you'll find an easy way to hook into the process and adapt your code to that process. You can see the code that does this here: https://api.drupal.org/api/drupal/modules%21user%21user.module/function/...
The reason to have the cart
The reason to have the cart in a separate table was to retain a copy of it in case the session/cookie disappeared - this has happened with several applications in the past, and the user-base is somewhat paranoid of it. In addition, we have an external application go through and remove all "expired" cart items. So, storing the cart in a cookie or session data is a non-starter - at least in this version.
Try as we might, we can't get the user-base to log in to place an order - they want to create an order anonymously, and then log in to submit it. Since these aren't captive users, they just don't place their orders.
But, back to the problem at hand -- no reliable session_id for anonymous users.
After some experimentation, it appears that the value returned by session_id() changes each time an anonymous user adds an item to the cart; but never changes when a logged in user adds an item. And (if we don't call drupal_session_initialize), its the same session_id for all anonymous users; logged-in users have their own.
I realize that session_id() is a php function and not a Drupal one, but because Drupal doesn't provide one that works for both anonymous and logged-in users, or a work-alike equivalent, it makes using session identifiers pretty useless for our application.
As a sort of back-door approach to getting users to log in (by not automatically logging them out), I am taking your advice of extending the session/cookie lifetimes to one year.
I'll try for the cart-in-a-cookie after I get this release out.
Keep in mind I'm not
Keep in mind I'm not suggesting you require users to log in for the cart functionality. The problem is that if users do log in, the session will get destroyed and reissued with a different ID. Drupal will preserve the data w/in the session, but if you store the data in a cart table with a reference to the sessionid, the data will be gone.
You might be better off rolling your own cart_id and storing that id value inside the users session. then using that to reference cart information in the DB table. Drupal does regular expired session purging during cron, so a cart_id might be a better unique reference to work with anyways. It would have the same net effect, and would play nicer with drupal's session handling environment.
The long story short: I wouldn't try to mess with sessions outside of normal recommended handling. You are really just asking for a lot of pain and heartache.
IP
The code you need to review is in drupal_session_initialize and extends from there.
https://api.drupal.org/api/drupal/includes%21session.inc/function/drupal...
Ummm. The logic makes sense,
Ummm. The logic makes sense, but it doesn't seem to reflect what I'm seeing - looks like a mix-up between PHP and Drupal sessions. session_id() and session_name() return values that are different from $_COOKIE['SESS...'].
And my understanding of what's going on goes down quickly from there as the following DPM output shows: http://www.brucedawson.com/tmp.d/Screenshot.png
Bruce, are you rolling your
Bruce, are you rolling your own shopping cart? If so, you are far braver than me.
Drupal 7's session management is a bit flaky, in my experience.
To be specific, and I realize this may not directly relate to your objectives, D7 core is critically flawed in its management of mixed-mode sessions -- i.e., sessions that switch the user between HTTPS and HTTP. The switch from SSL/HTTPS to HTTP actually reliably loses the session context. (You will find numerous hits re this by Googling phrases such as "drupal 7 session management https http mixed".)
I only mention this issue in case it does relate to your work. If it does, let me know and I will provide excruciatingly exhaustive details on the issue and how I have dealt with it on my Pantheon-hosted site.
Cheers,
Bob
Sigh. Yes, we have to use our
Sigh. Yes, we have to use our own shopping cart because the product database is external to Drupal.
I'm aware of the HTTPS/HTTP problems; fortunately they're not applicable as we're not concerned with securing shopping carts (yet).
SSL borken
FYI https://www.drupal.org/node/961508 is the issue at the heart of the mixed-mode security bug.
Good share!
Good share!
Jesse Nicola -- Shredical six different ways to Sunday! -- My Portfolio
Yes, that's right. Also
Yes, that's right, although I would not relegate the bug's scope to security only.
Also see:
https://drupal.org/node/1131986
https://drupal.org/node/1400880
https://drupal.org/comment/7648147#comment-7648147
https://drupal.org/node/2029353
Sessions
Drupal 6 and lower ran with a session being created for each anonymous user, but as of Drupal 7+ a php session is not created for anonymous users* (the one exception being, if a module has code that writes to the $_SESSION super global a session will get created).
This was in response to the notion (popularized by Pressflow) that most visitors to sites don't actually need a session, and reverse proxies and external caches could then use the existence of a session cookie to determine whether a cached element should be delivered or passed on.
I think Damien has it right when he says:
in regards to SSL:
If you need your session to be available mixed mode, my understanding is that browsers treat a switch in protocols like a switch in subdomains - the cookie has to specifically state at issue time that it is allowed to be on multiple 'domains'. This should be resolvable with the leading dot notation eg: $cookie_domain=".example.com"
Chris: Thanks! Your comment
Chris: Thanks!
Your comment goes a long way towards explaining things not covered by the holes in "documentation".
I don't need mixed mode (yet), so I'm not concerned with those issues. But thanks for implying that having a leading dot may solve mixed-mode problems!
--Bruce
I personally have fought a
I personally have fought a lot with the session and SSL issues with Drupal since I run a large eCommerce site on drupal.
For a long time I used securepages module but about a year and a half ago, I replaced it with secure login and also made the HTTP header changes to Apache that tells all good web browsers to only speak to the website in SSL (IE not being a good browser).
Since i have a login form on every page of my site via the logintoboggan button, the securelogin handles forcing everything SSL which is what I wanted - the mixed-mode and SSL switching stuff because a pain in the ass. So I made my entire site SSL :-D
The apache header tweak gives me even more reassurance that the entire site stays SSL. And now I even show up in all search engines as https and not http. Google "swing surgeon" to see.
Brady
@fastglassllc
@derailedonline
100 percent SSL works nicely
100 percent SSL works nicely as would be my preference ... provided you do not have some additional requirements on your hands that are incompatible with SSL.
My site utilizes mixed mode because it iframes external websites, namely those of my customers. The iframing renders nothing but an empty frame over SSL/HTTPS, so the class of pages that include iframed sites all utilize just plain HTTP.
It is when I put the iframed sites feature in play that I encountered the bizarre D7 handling of mixed-mode sessions and went far down the rabbit hole to ferret out (oh, an unintended pun!:) how to get things running robustly.
Oh I do at times long for the days of Java enterprise development and reliance on Apache and other Java-centric open source projects.
People think they only need
People think they only need to encrypt traffic to "sensitive" pages/forms but once a user has an authenticated session, if their session cookie is transmitted over plain HTTP when they go visit the "less-sensitive" pages it can be easily hijacked by anyone sharing the network. There's even a handy Firefox extension to help them out. https://en.wikipedia.org/wiki/Firesheep
Once a hacker has your session cookie they can then navigate to those "sensitive" pages and update your profile, change your password (at least in D6), use your admin privs and do all sorts of no good stuff.
While a lot of people think D7's lack of support for mixed mode sessions is a bug, I would call it a feature.
In an e-commerce setting, you can support anonymous sessions over HTTP. But the moment they do anything more sensitive than add something to their cart--log in, begin the checkout flow--you shuttle them to HTTPS (D7 supports "upgrading" an HTTP session to an HTTPS session) and don't send them back to HTTP (the way SecurePages does). You have to be disciplined in your development to make sure links, CSS, JS and iframes all respect the HTTPS scheme all over the site.
Oh, I understand about
Oh, I understand about man-in-the-middle attacks of non-https connections. But the owners don't want to spring for a couple of separate IP address to run a secure site. (And I'm one of the owners.)
I'm not that concerned. Once we get things working the way we like, and money starts coming in, then we can make the whole site https.
Amazon web services...
Amazon web services... Elastic IP addresses are cheap :-D
Brady
@fastglassllc
@derailedonline
Good points. Well taken. So,
Good points. Well taken.
So, is there a D7 way to fully and reliably render a link field (i.e., the URL of an external site) as a navigable iframed site inside of an HTTPS page?
Quick question. What are
Quick question. What are you iFraming?
Brady
@fastglassllc
@derailedonline
I was wondering what you were
I was wondering what you were iframing but I just wanted to throw in these comments none-the-less.
There are only two instances you EVER want to use iframes:
Any other reasons you should not use iframes. They are a nightmare and a vulnerability and extremely HIGHLY discouraged in building websites. iFrames can present a security hazards to your site. You should only iFrame sites that you trust or ones that offer some level of trust.
Brady
@fastglassllc
@derailedonline
Jumping back to the original question about anon users
First. What are you using for a shopping cart solution?
Drupal Commerce?
Ubercart?
Custom built shopping cart?
Well crap... I guess that question needs to be answered first.
I run a very large eCommerce site that does a substantial amount of sales per year and supplies digital content to make it even more complicated. I handle anonymous users like I do current users.
The best advice I can give you and it will save you more time than it will in cost: SSL the entire site. It makes life much easier and isn't that expensive. If it is with your current hosting solution then you need to find a new one. When my users enter a checkout process the are already SSL. You will drive yourself nuts dealing with sessions - I did - because Drupal doesn't support the mixing of sessions as someone here has already stated is a VERY GOOD design feature!
Brady
@fastglassllc
@derailedonline