Go Back   SitePoint Forums > Forum Index > Program Your Site > PHP > PHP Application Design
Newsletter FAQ Members List Calendar Mark Forums Read

New to SitePoint Forums? Register here for free!

SitePoint Sponsor
 
Reply
 
Thread Tools Display Modes
Old Oct 26, 2009, 15:17   #1
allspiritseve
SitePoint Evangelist
 
allspiritseve's Avatar
 
Join Date: Dec 2002
Location: Kalamazoo, MI (USA)
Posts: 569
Dealing with POST data and expired sessions

Ok, so a client has discovered that when she leaves her add blog post page open long enough for the session to expire, and then tries to submit, she is logged out and her data lost. Needless to say, that's not desired.

I have some ideas about how to solve this, but I wanted to run it by all of you before I start coding. First of all, I'd like to use cookies to keep the user logged in for 30 days unless they request a shorter session at login (for when they are logging in remotely, library or internet cafe, whatever).

Next, I'm thinking the best way to maintain that POST data is to throw it in the session. Because the session data is lost, I will probably need to store sessions in the database (more secure anyways, right?) and reload that session from a cookie value upon successful relogin. Can anyone think of a better way to handle this?
allspiritseve is offline   Reply With Quote
Old Oct 26, 2009, 15:40   #2
ScallioXTX
SitePoint Evangelist
 
ScallioXTX's Avatar
 
Join Date: Aug 2008
Location: The Netherlands
Posts: 525
Quote:
Originally Posted by allspiritseve View Post
Ok, so a client has discovered that when she leaves her add blog post page open long enough for the session to expire, and then tries to submit, she is logged out and her data lost. Needless to say, that's not desired.

I have some ideas about how to solve this, but I wanted to run it by all of you before I start coding. First of all, I'd like to use cookies to keep the user logged in for 30 days unless they request a shorter session at login (for when they are logging in remotely, library or internet cafe, whatever).

Next, I'm thinking the best way to maintain that POST data is to throw it in the session. Because the session data is lost, I will probably need to store sessions in the database (more secure anyways, right?) and reload that session from a cookie value upon successful relogin. Can anyone think of a better way to handle this?
We had the same problem with one of our clients and thought of (but did not implement so it's not the tested) the following:

On a page of the website where the user can edit content like a blog entry you send an AJAX request to a very simple php script

PHP Code:

session_start(); 

That should prolong the time of the session. I guess using session_regenerate_id() might cause trouble since the cookie than received by the AJAX request with the new session id might not be processed by the browser, thus effectively logging out because the user's cookie's rendered useless / outdated.
If you send such a call every minute or every two miniutes or something it causes almost no data traffic at all and your client should stay logged in
ScallioXTX is offline   Reply With Quote
Old Oct 26, 2009, 15:51   #3
allspiritseve
SitePoint Evangelist
 
allspiritseve's Avatar
 
Join Date: Dec 2002
Location: Kalamazoo, MI (USA)
Posts: 569
That's not always ideal (though probably better than our current setup). Sometimes you want the session logged out with a short period of inactivity. Using cookies will allow us to keep user data virtually as long as we want-- but it still doesn't protect against lost POST data.

I have seen on other sites, if I post data and them am redirected to a login page because my session expired, once I log in it tells me it completed the action I was trying to complete before it redirected. I would hope that it is somehow saving the action to be completed until after I log in, and not just completing the action and then telling me to log back in (thus opening up the script to fake POST requests that can modify data).
allspiritseve is offline   Reply With Quote
Old Oct 26, 2009, 16:09   #4
jameso
SitePoint Enthusiast
 
Join Date: May 2002
Location: Melbourne, Australia
Posts: 73
I have never actually tried to implement this, but I think vBulletin handles this situation by somehow storing the submitted data, displaying the login form, logging the user in, then "resending" the submitted data again.
jameso is offline   Reply With Quote
Old Oct 27, 2009, 01:56   #5
kyberfabrikken
SitePoint Mentor
 
kyberfabrikken's Avatar
 
Join Date: Jun 2004
Location: Copenhagen, Denmark
Posts: 5,819
www-authentication solves all youor problems. If you don't want to use it as the primary login mechanism, you can fall back to it when your session based login fails.
kyberfabrikken is offline   Reply With Quote
Old Oct 29, 2009, 13:25   #6
allspiritseve
SitePoint Evangelist
 
allspiritseve's Avatar
 
Join Date: Dec 2002
Location: Kalamazoo, MI (USA)
Posts: 569
Quote:
Originally Posted by kyberfabrikken View Post
www-authentication solves all youor problems. If you don't want to use it as the primary login mechanism, you can fall back to it when your session based login fails.
Cool I will look into that.

Quote:
Originally Posted by paalg
What if the login page receives the posted data (POST) and the URL it came from, and the login page leads her back to where she was with the data she submitted after successful login?
That would have to be done with sessions, and was my initial thought. It seems like it should fit in well with a post-redirect-get mechanism.

Quote:
Originally Posted by Ren
Why not always ask for a username / password on a form?
Interesting thought. My guess is it would be confusing to most users, though. ("Why do I have to log in every time I edit a page?")

Quote:
Originally Posted by Selkirk
A 12 hour session expiry works for a workday.
Quote:
Originally Posted by Stomme poes
Uh, doesn't 30 days seem a little long? What's wrong with 24 hours?
Didn't really have a specific reason for 30 days, just wanted something longer that clients don't have to think about.
allspiritseve is offline   Reply With Quote
Old Oct 27, 2009, 04:57   #7
paalgg
SitePoint Member
 
Join Date: Nov 2005
Location: Molde, Norway
Posts: 18
Quote:
Originally Posted by allspiritseve View Post
Ok, so a client has discovered that when she leaves her add blog post page open long enough for the session to expire, and then tries to submit, she is logged out and her data lost. Needless to say, that's not desired.
What if the login page receives the posted data (POST) and the URL it came from, and the login page leads her back to where she was with the data she submitted after successful login?
paalgg is offline   Reply With Quote
Old Oct 27, 2009, 11:36   #8
Ruben K.
SitePoint Guru
 
Ruben K.'s Avatar
 
Join Date: Jun 2005
Location: Alkmaar, The Netherlands
Posts: 673
What you COULD do is make a javascript that requests a blank page with AJAX which has got session_start() on it, have the javascript execute the AJAX every 60 seconds and in theory this would result in the session never expiring ;-)
Ruben K. is online now   Reply With Quote
Old Oct 27, 2009, 12:59   #9
kyberfabrikken
SitePoint Mentor
 
kyberfabrikken's Avatar
 
Join Date: Jun 2004
Location: Copenhagen, Denmark
Posts: 5,819
Quote:
Originally Posted by Ruben K. View Post
What you COULD do is make a javascript that requests a blank page with AJAX which has got session_start() on it, have the javascript execute the AJAX every 60 seconds and in theory this would result in the session never expiring ;-)
In that case, simply setting session.gc_maxlifetime to a higher value is probably a better solution.
kyberfabrikken is offline   Reply With Quote
Old Oct 27, 2009, 17:29   #10
Ren
SitePoint Guru
 
Ren's Avatar
 
Join Date: Aug 2003
Location: UK
Posts: 934
Why not always ask for a username / password on a form?

If the user session is valid then it is optional. If it expires whilst the user has the form open, then treat like a validation error, and redisplay the form.
Ren is online now   Reply With Quote
Old Oct 28, 2009, 02:16   #11
Stomme poes
Site Point Member
 
Stomme poes's Avatar
 
Join Date: Aug 2007
Location: Netherlands
Posts: 2,677
Quote:
First of all, I'd like to use cookies to keep the user logged in for 30 days unless they request a shorter session at login (for when they are logging in remotely, library or internet cafe, whatever).
Uh, doesn't 30 days seem a little long? What's wrong with 24 hours? How many people will miss that they can request a shorter session? Should we trust the user to set more security, or is it better to set more security and let the user remove it (for their own harm, done by their own hand)?

For those suggesting AJAX, what would be the solution for users with mobiles and other devices likely to have JS off? (kyberfabrikken's solutions?)

Often when I'm told to go log in again, I'll hit my back button, copy-pasta what I wrote, then go back forward and try logging in (this works because the POST didn't happen and instead I get a different URL sent to me, so my info isn't lost, but is still in my browser cache). Sometimes logging back in doesn't work due to server loads (was very common on a forum I am on), so I can always paste what I wrote in a text editor just-in-case.
Stomme poes is offline   Reply With Quote
Old Oct 30, 2009, 02:58   #12
webaddictz
SitePoint Zealot
 
Join Date: Feb 2006
Location: Netherlands
Posts: 174
Quote:
Originally Posted by Ren View Post
Why not always ask for a username / password on a form? If the user session is valid then it is optional. If it expires whilst the user has the form open, then treat like a validation error, and redisplay the form.
Interesting thought indeed. I've had this problems with users that were writing something along the length of the bible in a textarea, and they were surprised when they found out that they were logged out in the meantime and naturally, that had upset them as they now lost the text they wrote. When I explain it's a security precaution, they will usually calm down, but I really feel bad for the users: there has to be a way around it.

I do agree with allspiritseve though: always asking them for their username and password will confuse the users of my applications, and very understandable too, I think I'd be confused just as well as my end-users. I mean, while writing this reply, I wouldn't expect that I'd have to pass along my username and password, as it already says: "Logged in as webaddictz".

I do, however, think there is a middle ground? When the form is submitted, check if there is a session, if there is not, save the information somewhere and redirect the user to a login page. After login, send them back to the form and let them submit again. No Ajax involved, and it will work on every browser.

You could, of course, create an Ajax variant too. Upon submittal of the form, do an Ajax call to see if the session is still alive. If not, ask the user to fill out username and password, and submit that with form. On the serverside, log the user in and save the form's value(s). That actually sounds like a nice idea.
webaddictz is offline   Reply With Quote
Old Oct 30, 2009, 03:23   #13
kyberfabrikken
SitePoint Mentor
 
kyberfabrikken's Avatar
 
Join Date: Jun 2004
Location: Copenhagen, Denmark
Posts: 5,819
Quote:
Originally Posted by webaddictz View Post
Interesting thought indeed.

...

I do, however, think there is a middle ground? When the form is submitted, check if there is a session, if there is not, save the information somewhere and redirect the user to a login page. After login, send them back to the form and let them submit again. No Ajax involved, and it will work on every browser.
Yes, I liked that suggestion too. I think you're over complicating it though.

What about you just show the form as usual. When the user submits it; if the session has expired you redisplay the form with the user + pass fields added to it (And the rest of the fields filled in from post data). That way, the normal flow would work unchanged, and you only do something different if the users session has expired. Basically, you treat the expired session as a validation error on the form, which is actually quite intuitive (IMHO).

If you wanted, you could even redisplay the page with the original content in hidden fields, and only the new user + pass fields displayed. This gives an illusion about being redirected to a login page, when - in fact - there is no redirection going on. Since there is no actual redirect, you don't need to temporarily store the form contents in session or elsewhere.
kyberfabrikken is offline   Reply With Quote
Old Oct 30, 2009, 03:45   #14
webaddictz
SitePoint Zealot
 
Join Date: Feb 2006
Location: Netherlands
Posts: 174
Quote:
Originally Posted by kyberfabrikken View Post
Yes, I liked that suggestion too. I think you're over complicating it though.
Well, over-complicating is easier than keeping things simple, unfortunately. I guess you're right

Quote:
Originally Posted by kyberfabrikken View Post
What about you just redisplay the form with the user + pass fields added to it, if the users session has expired. Then have the user submit again. That way, the normal flow would work as usual, and you only do something different if the users session has expired. Basically, you treat the expired session as a validation error on the form, which is actually quite intuitive (IMHO).
That actually sounds like a better, less cluttered way of achieving the same. The user would probably be a lot happier with this. It does make sense: the fact that a user's session is expired is just another possible validation error. I can see one potential pitfall though: when a non logged-in user is not allowed to view any entries, let alone edit them, where will you validate whether or not you should actually display the page, seeing that an expired session essentially equals a user that is not logged in.

Or is this something we shouldn't be afraid of? The only way the user + pass form entries will be shown is upon a POST, so a non-logged in user would have to guess the correct URL and submit a POST request which includes the values that are to be written and so he doesn't have the ability to override if he's not allowed to and can't read it because the GET would give an error.

Gosh, you're right. I am over-complicating. This is a viable, secure and very user-friendly option and I'll be writing this in my newest applications from here-on now.

Quote:
Originally Posted by kyberfabrikken View Post
This gives an illusion about being redirected to a login page, when - in fact - there is no redirection going on. Since there is no actual redirect, you don't need to temporarily store the form contents in session or elsewhere.
By keeping the state at the client, and not the server, things do become less complicated, this is a very nice example of that. No Javascript magic, no complicating stuff like temporarily storing values, just another POST. Sounds darn good to me.
webaddictz is offline   Reply With Quote
Old Oct 30, 2009, 04:44   #15
kyberfabrikken
SitePoint Mentor
 
kyberfabrikken's Avatar
 
Join Date: Jun 2004
Location: Copenhagen, Denmark
Posts: 5,819
Quote:
Originally Posted by webaddictz View Post
I can see one potential pitfall though: when a non logged-in user is not allowed to view any entries, let alone edit them, where will you validate whether or not you should actually display the page, seeing that an expired session essentially equals a user that is not logged in.
You would use the POST data from the request to populate the form, so I don't see any security problem there.
kyberfabrikken is offline   Reply With Quote
Old Oct 30, 2009, 06:08   #16
tetsuo shima
SitePoint Evangelist
 
tetsuo shima's Avatar
 
Join Date: Oct 2005
Location: Switzerland
Posts: 577
Hi
Quote:
Originally Posted by kyberfabrikken View Post
What about you just show the form as usual. When the user submits it; if the session has expired you redisplay the form with the user + pass fields added to it (And the rest of the fields filled in from post data). That way, the normal flow would work unchanged, and you only do something different if the users session has expired. Basically, you treat the expired session as a validation error on the form, which is actually quite intuitive (IMHO).
I use a similar approach, only I open a modal with login and pwd. If credentials are accepted, the form is submitted. After three errors, the content is saved into a db (as a draft, for a later use), and the user redirected to the usual login page.

tetsuo shima is offline   Reply With Quote
Old Oct 30, 2009, 06:14   #17
Ren
SitePoint Guru
 
Ren's Avatar
 
Join Date: Aug 2003
Location: UK
Posts: 934
Quote:
Originally Posted by kyberfabrikken View Post
Yes, I liked that suggestion too. I think you're over complicating it though.

What about you just show the form as usual. When the user submits it; if the session has expired you redisplay the form with the user + pass fields added to it (And the rest of the fields filled in from post data). That way, the normal flow would work unchanged, and you only do something different if the users session has expired. Basically, you treat the expired session as a validation error on the form, which is actually quite intuitive (IMHO).

If you wanted, you could even redisplay the page with the original content in hidden fields, and only the new user + pass fields displayed. This gives an illusion about being redirected to a login page, when - in fact - there is no redirection going on. Since there is no actual redirect, you don't need to temporarily store the form contents in session or elsewhere.
Yeah. Should be also able to prefill the user field, if they were logged on when they opened the page containing the form.

So if they post after their login credentials expire, just need the user to enter their password.
Ren is online now   Reply With Quote
Old Oct 28, 2009, 07:58   #18
Vali
SitePoint Evangelist
 
Vali's Avatar
 
Join Date: Jun 2006
Posts: 443
What you need to do is this:

#1 make sure all your forms post to them-selfs (302 to them-selfs on success, so you don't have the "refresh" confirmation popup)

#2 - In case you have an "if (is not logged in) { redirect to login page; }" block in more than one place, put that in a function and call that function everywhere.

#3 - In that function, before the actual redirect, check 2 things:
a) If the request was GET, and if so, store the URL in a session variable (redirect to it after login)
b) If the request was a POST, store the #1 the URL and #2 the posted data in the session. Redirect to that #1 URL after the login, and use the #2 data to pre-populate the form fields on the page.
(Make sure to tie the data to the logged in user id or something)

So, from the user's point of view:
- login
- go to edit profile
- fill in profile
- chase bag in the wind for 45 min (session is 15)
- come back, submit the edit profile page
--- get a "login here" page.
- login
--- get redirected to the submitted page, pre-populated with all the posted data, and some kind of message saying to repost, since the data was not saved cause of session time out.

Hope that helps.
Vali is offline   Reply With Quote
Old Oct 28, 2009, 08:51   #19
Selkirk
SitePoint Guru
 
Join Date: Nov 2002
Posts: 845
A 12 hour session expiry works for a workday. They basically have to re-login the next day. If you leave the form overnight, do you really need to still be able to submit it?

I haven't implemented the solution to this myself, but we've using a ping to renew the session cookie. We've also used a count down timer to warn the user that they should submit soon, or at least go through a preview cycle to renew their session.
Selkirk is offline   Reply With Quote
Old Nov 2, 2009, 03:49   #20
Florent V.
SitePoint Enthusiast
 
Join Date: Apr 2009
Location: Lyon, France
Posts: 54
Hello,

Additionally, have your clients use Firefox and the Lazarus extension. Lazarus saved my life several times in the past few weeks. Well, not my life, but a few combined hours of work.
Florent V. is offline   Reply With Quote
Old Nov 2, 2009, 05:30   #21
Stomme poes
Site Point Member
 
Stomme poes's Avatar
 
Join Date: Aug 2007
Location: Netherlands
Posts: 2,677
So what's the Opera version of that, Florent? : )
Stomme poes is offline   Reply With Quote
Old Nov 5, 2009, 01:20   #22
webaddictz
SitePoint Zealot
 
Join Date: Feb 2006
Location: Netherlands
Posts: 174
Quote:
Originally Posted by Stomme poes View Post
So what's the Opera version of that, Florent? : )
Stomme Poes, Opera is intelligent enough to do this by default. It keeps your written text in memory, even if you (accidentally) browse away from the page and come back to it.
webaddictz is offline   Reply With Quote
Old Nov 5, 2009, 05:13   #23
Stomme poes
Site Point Member
 
Stomme poes's Avatar
 
Join Date: Aug 2007
Location: Netherlands
Posts: 2,677
Quote:
Stomme Poes, Opera is intelligent enough to do this by default. It keeps your written text in memory, even if you (accidentally) browse away from the page and come back to it.
Great to hear, so what's the Safari or Chrome versions of this Lazarus?

My point wasn't how to do it in Opera, but that we often cannot tell clients to use browser-X with extension-Y except ion rare cases, so I was questioning it. It's okay to suggest it, but you have to still build for without it (unless this is internal application of course).
Stomme poes is offline   Reply With Quote
Old Nov 4, 2009, 07:55   #24
Dorsey
SitePoint Enthusiast
 
Dorsey's Avatar
 
Join Date: Feb 2004
Location: NJ
Posts: 96
We invoke session_start() on every page, test for a login cookie on every page that processes form data, and ALL form pages POST back to themselves. If the cookie test fails, we save the current URL and POST as session data, re-direct to a login page, and finally return from whence the user came to the saved URL. Each form tests for POST session data and uses that if found; that is, we restore POST from the saved session data, then remove the session data. It seems to work.
Dorsey is offline   Reply With Quote
Old Nov 8, 2009, 18:00   #25
crmalibu
SitePoint Wizard
 
Join Date: Jul 2008
Posts: 4,770
You don't necessarily have a problem with the back button if you don't redirect. This is more an effect of certain http headers being sent(primarily certain cache-control headers). btw, session_start() sends cache-control headers in addition to the potential session cookie header.
crmalibu is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread | Next Thread »

Thread Tools
Display Modes

 
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Sponsored Links
 
Forum Jump


All times are GMT -7. The time now is 07:15.


Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Copyright 1998-2009, SitePoint Pty Ltd. All Rights Reserved