JBF's avatar
Level 3

Are long sessions bad?

Ok, I know that's too general a question. So to expand...

For an e-commerce platform, would it be considered bad practice to have a long session length so that items in the basket or view settings (list or grid, order by, etc) are stored in between visits?

Obviously, the authentication would be kept to a secure, short time. The default in the Laravel auth config is 3 hours and I would be happy if the user has to re-authenticate every 3 hours to get to protected content.

I've tried to investigate this issue online but I find so many different opinions that I can't decide. For the site I'm working on, I think a 1 month session length would give a good UX experience. But is this too long from a security point of view? Thanks.

0 likes
19 replies
Snapey's avatar

session length and authentication are inextricably tied together.

I cant think of a way where the user's session could continue after logout.

But, there are other ways of storing the user's basket, especially if they are authenticated.

Back to your question. Session length could be extended but a) you are extending the opportunity for someone else to mess with their session if they have access to their computer, and b) if your site was really busy, you would have a lot of session data lying around.

You should also consider the user that would like to continue with their basket on a different device or even different browser on the same device.

JBF's avatar
Level 3

Thanks Snapey. That's helpful.

If a user explicitly logs out, then yes I would consider that a clear signal to end the session. And yes, whilst the user is logged in, the basket and view settings can be stored in the database.

But that leaves two scenarios -

  1. Before the user registers. New clients who are spending some time thinking about a purchase.

  2. A registered user on a device they use regularly where they don't feel the need to log out. In this case, if we only store the basket and view settings in the DB, then the user has to re-authenticate even for content which is not sensitive and generally has no need to be secure. (unless they are buying gifts for their affair!)

I take your points A + B on board. In the case of what I'm building, I don't think either would be a big issue. Are there any other security issues to consider?

But I guess what I'm really trying to establish is this - is there an accepted best practice for session length for e-commerce? Something that balances security, user experience and conversion rates. I've been looking at some big online retailers and the expiry dates on their cookies, and of course, I don't know what each cookie relates to but many of them expire in 1 year and some in many years. Could they be storing the user session for a year?

Snapey's avatar

They could be storing the session in the cookie (although it only stores 4k) but more likely they store an id of the basket so that unauthenticated users can be repatriated with their basket when they come back.

This would be independent of their session cookie.

jlrdw's avatar

You could just make it like a pending invoice. Store the data, and after a certain time goes by delete. If 2 months goes by and they haven't finished order it's no good no more.

2 months is just an example.

I would not hold session data.

JBF's avatar
Level 3

Thanks both of you for the advice.

So, maybe I started with the wrong question. Sounds like I should have asked, what's the recommended way of storing a shopping basket? One that allows unauthenticated users to keep their basket for a decent length of time and allows authenticated users to use their basket on multiple machines.

Do you think storing the database id of a shopping basket in a cookie is the way to go? With a field on the user table to store the basket id once they log in? Maybe merging the contents if they differ? Then just delete any idle baskets not associated with a user after a certain length of time.

Snapey's avatar

almost. create the basket with an id for the user on the basket once they login (I would do it the other way around to your suggestion)

The basket is unowned or belongsTo user. If its unowned then it just sits there until someone with a matching cookie turn up, or you housekeep it.

JBF's avatar
Level 3

Thanks Snapey. This is starting to make sense to me but I'm still a little confused. Why do you need a separate cookie for the shopping basket? Couldn't the basket table have a field for the session id? I don't understand why it's dangerous to have a long session cookie timeout but safe to have a long basket cookie timeout? Is it considered good practice that the session is reserved for authenticating users and flash messages and not much else? Sorry, you can tell that I'm a hobby coder rather than a professional ;-)

jlrdw's avatar

@jbf I wouldn't hold that data for people not logged in I would Reserve orders for logged in customers. For example before I join Amazon I was placing an order and changed my mind, they don't save orders for non logged-in users.

Just saying this is going to become a mess if suddenly you have a thousand proposed orders and they never come back.

JBF's avatar
Level 3

@jlrdw Thanks but that seems to contradict your previous comment? I guess I'm not understanding right... The default session in laravel is 2 hours. If I don't extend the session and i don't store the basket in the database with a reference in a cookie, the user will lose their basket after 2 hours. This could just be having lunch and walking the dog! Sometimes I might take a few weeks to make a purchase if I'm buying something expensive. If the site sells lots of items, the quickest way to find what I'm thinking about is to return to my basket. So, I think even for unregistered users, storing the basket for at least a month is sensible for conversions. Or do you mean that I shouldn't store a basket for every visitor? Just people who put something in their basket? That makes sense to me.

JBF's avatar
Level 3

@jlrdw actually, sorry, I do understand what you mean, I was reading too quickly! But my point still stands, I think from the point of view of making sales, it would be best to store the basket of potential new customers for a decent time.

JBF's avatar
Level 3

@snapey I've just realised that I misunderstood how session cookies work. I've just been checking and it seems the session cookie value is regenerated every time the page is loaded. But I suppose you could store the ID of the basket in the session for unauthenticated users. I still don't understand why it is better to have a separate cookie for that?

Snapey's avatar

The session cookie will expire, and also be overwritten by a new session cookie next time the user comes to the site.

By using a separate basket cookie, this can have a long lifetime and wont be overwritten unless you want it to be

jlrdw's avatar

One last attempt, first see https://stackoverflow.com/questions/12569568/shopping-cart-persistence-session-or-browser-cookie

If I don't complete my order, and later decide to finish, I may use a completely different computer.

I may have started on my Samsung tablet, but decide to finish on my desktop. Why do you think I suggested storing in db.

You are expecting too much out of your non customers, before they even become a customer.

Furthermore many folks use CCleaner (and similar) to clear cookies anyway.

Snapey's avatar

so @jlrdw you are suggesting that everyone must sign up for an account before putting anything in their basket

jlrdw's avatar

No, like I said, store the data in the the db. Maybe a "potential customer table" . Look at it like a pending invoice.

In a save cart option, at least get an email, so later you have a way to pull pending order.

But I would not do this, but OP seems to want to hold possible future customers. 99.99% will probably never return to that order.

Just my opinion.

So if an increase in price, do they get the original "held" price.

JBF's avatar
Level 3

@jlrdw In my own experience, I often put things in my basket before I sign in. Also, I often return to a website a few times before I decide to go ahead. A perfect example would be a website selling clothes. I'm sure many people use their basket as a place to collect "items they're thinking about" and then when they're ready, they make the final selection and proceed with the purchase. So, they could easily take a few days to go through that process. For very expensive items, for instance jewellery, I'm sure many people deliberate for weeks. In fact the more expensive the item, probably the better retail logic to make sure the basket is remembered. No-one wants to lose a high value sale.

So, there are definitely situations where storing, in some manner, the basket of a user either unregistered or not logged in, makes good sense. I agree that this won't work / be needed for all use cases. And yes, I would think any basket should be checking for changes in stock and pricing, every time it is instantiated.

I guess whether you use a separate DB table for the basket of a logged in user vs a not logged in user, would be a case of coding style. However, i'm not sure that I can see any benefit? It's trivial to check the last_modified date of all entries without a user_id and delete them after a certain length of time.

JBF's avatar
Level 3

@jlrdw ps. thanks for that link. It is a helpful discussion

JBF's avatar
Level 3

@snapey So whenever I visit a website, like Amazon, where they keep me logged in but not authenticated, or they remember my settings between visits, that will / should be done with a cookie, not a long session length? I don't fully understand why that is better, but if that is the best practice, I'm happy to follow it.

There is just one last problem that I'm not sure how to solve. If my session stays at the laravel default of 2 hours, if my user leaves the page open and goes away for a while, for instance, they start browsing at night and return to the page in the morning, the session has ended. So, if they then click any view settings; order by price, filters, grid vs list etc. Or if they are on a contact us page and complete a form, or a product page and add to basket, the CSRF will fail and the user will have to repeat the action after the page refreshes. This is a nasty user experience. Is there a good solution for this problem? To get around it could I extend the session to say 1 week? If a user leaves a page open that long and doesn't use it, I think it's reasonable to require a refresh but every 2 hours seems annoying to me.

Snapey's avatar

make the session as long as you like. I said why this might not be good earlier - but as ever, use cases vary.

Please or to participate in this conversation.