Jump to content

How to manage expired login sessions gracefully


Norm

Recommended Posts


When a user accesses a site and a login form is shown, the session expiry countdown starts immediately. This means the session can expire without the user having logged in. If the user subsequently submits a login request the ugly "Invalid session or session Timeout..." message is displayed on the users browser. The message looks specially awful on mobile devices and hints at immature (un-robust?) web design.

Is there any way one can intercept this default http handling and instead automatically start a new session and re-display the login screen, maybe with an optional "expired session" flag so an appropriate message can be displayed to the user?

I am having this issue especially with mobile-phone users who, at the end of a their visit, log out and put the phone away without closing the browser. This means the login screen can remain displayed for many hours until the next time they attempt to log in.

Any suggestion on how to handle this?
 

Link to comment
Share on other sites

1 hour ago, Norm said:

Is there any way one can intercept this default http handling and instead automatically start a new session and re-display the login screen, maybe with an optional "expired session" flag so an appropriate message can be displayed to the user?

Hello,

Please see the Options property:

UniServerModule.Options = soRestartSessionOnTimeout = True

Also these demos:

\FMSoft\Framework\uniGUI\Demos\Desktop\SessionTimeout
\FMSoft\Framework\uniGUI\Demos\Desktop\Session Idle Timeout

 

Link to comment
Share on other sites

Sherzod,

Thank you for responding so promptly.

I am familiar with the options you mentioned and I use SessionTimeout extensively.

As for RestartSessionOnTimeout, I never use it because I think it is bad practice for the following reasons:

- Like all respectable web portals I monitor user idle-time and forcibly log the user out after displaying a warning if threshold is exceeded. RestartSessionOnTimeout would make this standard-practice behavior redundant.

- RestartSessionOnTimeout is a bad use of resources, especially for mobile devices (which applies in my case). Imagine having to keep dozens of sessions alive when their users are walking around with their phones in their pockets.

I think sessions should be allowed to expire for the sake of security and resource optimization, but uniGui should let developer decide how to handle resulting issues, in the same way as Delphi lets us to handle exceptions. I think the message "Invalid session or session Timeout..." is a blunt tool that is very unfortunate and a bit embarrassing. It seems uniGui is the only framework that has this issue. Other frameworks provide the option to redirect to an Expire Session page.

As an alternative can I suggest a new so option that will start a new session if the http session does not exist.

I would be interested to know what fellow uniGue developers think.

 

Link to comment
Share on other sites

On 9/19/2021 at 7:29 AM, Norm said:

....can I suggest a new so option that will start a new session if the http session does not exist.

Hello Norm,

an old solution is to put an empty Unitimer on loginform.

By this way, the session will never come out.

But, as you have mentionned, this is a bad practice as it will maintain hundreds sessions live and consume many ressources.

Link to comment
Share on other sites

hello @Norm I made my own procedure for ended sessions:

TUniServerModule.UniGUIServerModuleBeforeInit
urlMessage := '<html>'
              + '<style>'
              + '.button {'
              + '  border: none;'
              + '  color: white;'
              + '  padding: 16px 32px;'
              + '  text-align: center;'
              + '  text-decoration: none;'
              + '  display: inline-block;'
              + '  font-size: 16px;'
              + '  margin: 4px 2px;'
              + '  transition-duration: 0.4s;'
              + '  cursor: pointer;'
              + '  border-radius: 12px;'
              + '  box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);'
              + '  margin: 0;'
              + '  position: absolute;'
              + '  top: 10%;'
              + '  left: 50%;'
              + '  -ms-transform: translate(-50%, -50%);'
              + '  transform: translate(-50%, -50%);'
              + '}'
              + '.button1 {'
              + '  background-color: white;'
              + '  color: black;'
              //+ '  border: 2px solid #4CAF50;'
              + '}'
              + '.button1:hover {'
              + '  background-color: #4CAF50;'
              + '  color: white;'
              + '}'
              + '</style>'
              //reload page
              + '<script>'
              + 'function redirect() {location.href = window.location.href;}'
              + '</script>'
              + '<body bgcolor="#dfe8f6">'
              + '<p style="text-align:center;color:#0000A0">[###message###]</p>'
              + '<button class="button button1" type="button" onclick=redirect()>Restart application</button>'
              + '</body>'
              + '</html>

              ;

ServerMessages.ExceptionTemplate.Text := urlMessage;
ServerMessages.InvalidSessionTemplate.Text := urlMessage;
ServerMessages.TerminateTemplate.Text := urlMessage;
 

here is result: 

image.png.e1ce802df86261688978aa2462b4c08c.png

So i make too:

1. Short sessions timeout - 30 minutes

2. uniTimer to check user activite and close session (Browser closed or no user activities)

3. I have no Timer on login form (session expired after 30 minutes), but after login:

 Timer is activated and this keep session alive forever. That make me to create:

     3.1 every 15 min i ask from user to confirm if is there . Wait 15 second answer from user and close session if not answer.

     3.2 Wait 30 minutes for user activities  and close session if no activities. This is solution if user close browser, stop internet or is passive (no activities)

All this is in file with user settings.

Points 3.1 and 3.2 make the same (close session if no user activities), so one of them is enough. I allow with user settings to choose how the application works.

 

  • Like 1
  • Thanks 1
  • Upvote 1
Link to comment
Share on other sites

4 hours ago, irigsoft said:

hello @Norm I made my own procedure for ended sessions:

TUniServerModule.UniGUIServerModuleBeforeInit
urlMessage := '<html>'
              + '<style>'
              + '.button {'
              + '  border: none;'
              + '  color: white;'
              + '  padding: 16px 32px;'
              + '  text-align: center;'
              + '  text-decoration: none;'
              + '  display: inline-block;'
              + '  font-size: 16px;'
              + '  margin: 4px 2px;'
              + '  transition-duration: 0.4s;'
              + '  cursor: pointer;'
              + '  border-radius: 12px;'
              + '  box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);'
              + '  margin: 0;'
              + '  position: absolute;'
              + '  top: 10%;'
              + '  left: 50%;'
              + '  -ms-transform: translate(-50%, -50%);'
              + '  transform: translate(-50%, -50%);'
              + '}'
              + '.button1 {'
              + '  background-color: white;'
              + '  color: black;'
              //+ '  border: 2px solid #4CAF50;'
              + '}'
              + '.button1:hover {'
              + '  background-color: #4CAF50;'
              + '  color: white;'
              + '}'
              + '</style>'
              //reload page
              + '<script>'
              + 'function redirect() {location.href = window.location.href;}'
              + '</script>'
              + '<body bgcolor="#dfe8f6">'
              + '<p style="text-align:center;color:#0000A0">[###message###]</p>'
              + '<button class="button button1" type="button" onclick=redirect()>Restart application</button>'
              + '</body>'
              + '</html>

              ;

ServerMessages.ExceptionTemplate.Text := urlMessage;
ServerMessages.InvalidSessionTemplate.Text := urlMessage;
ServerMessages.TerminateTemplate.Text := urlMessage;
 

here is result: 

image.png.e1ce802df86261688978aa2462b4c08c.png

So i make too:

1. Short sessions timeout - 30 minutes

2. uniTimer to check user activite and close session (Browser closed or no user activities)

3. I have no Timer on login form (session expired after 30 minutes), but after login:

 Timer is activated and this keep session alive forever. That make me to create:

     3.1 every 15 min i ask from user to confirm if is there . Wait 15 second answer from user and close session if not answer.

     3.2 Wait 30 minutes for user activities  and close session if no activities. This is solution if user close browser, stop internet or is passive (no activities)

All this is in file with user settings.

 

Very interesting IrigSoft,

+1

Can you please send a small sample project with these technics.

Thx.

Link to comment
Share on other sites

in mainform, script paste this

 

var IDLE_TIMEOUT = 600; //10 min
var _idleSecondsCounter = 0;
document.onclick = function() {
    _idleSecondsCounter = 0;
};
document.onmousemove = function() {
    _idleSecondsCounter = 0;
};
document.onkeypress = function() {
    _idleSecondsCounter = 0;
};
window.setInterval(CheckIdleTime, 5000); // 5 seconds

function CheckIdleTime() {
    _idleSecondsCounter++;
    var oPanel = document.getElementById("SecondsUntilExpire");
    if (oPanel)
        oPanel.innerHTML = (IDLE_TIMEOUT - _idleSecondsCounter) + "";
    if (_idleSecondsCounter >= IDLE_TIMEOUT) {
        ajaxRequest(FrmPrincipal.form, '_idle_timeout', []);
    }
}

 

 

in mainform events, onAjaxEvent

  if EventName = '_idle_timeout' then
    begin
      uniGUIApplication.UniSession.Terminate('you message');
    end;

 


this timer is running on the client side, without access to the server, and crashes the application after 600 seconds of no activity.
you can change this by changing the value of the variable
IDLE_TIMEOUT


if you want to do the same before logging in, you must do the same on the login screen

Link to comment
Share on other sites

Hi Irigsoft,

Thank you for sharing your ended session procedure. It will save me a lot of time.

Interesting regarding your session timeout monitoring strategy. I do more or less the same thing, i.e. server-side timer starts after successful login and session runs forever as long as I hear from the user periodically. What I do differently is this:

- I have a timer running on the client-side that monitors keyboard & mouse activity. As long as there is activity the client-side timer sends a ping to the sever every 2 minutes. If there is no activity for 15minutes the ping stops.

- Every ping from the client restarts the timeout count on the server side.

- If server-side timer expires I trigger a client-side “Submit & Logout” function (the project is a time-sheet recording system and I don’t want the user to lose any information they have entered and not yet submitted). If there is no unsaved data the procedure will simply send a logout request.

- If I don’t hear from the client within 2 seconds of this I force a logout procedure (free resources etc.) and display the login screen.

The problem I’ve had so far (that is what started this topic) was what to do with cases where I display a login screen and the user never responds. Now that I know about the user-defined expired-session procedure (thanks Sherzod) I monitor the session timeout event and let the session expire if the user does not respond within 5minutes. This is the only case where I use the session timeout (i.e. login timeout).

Link to comment
Share on other sites

3 hours ago, irigsoft said:

@Abaksoft Here is it:

Project5.zip 15.89 kB · 6 downloads

 

Proposal from wilton_rad is useful too on client side.

Thank you IrigSoft,

When runing the appli I have an AV on :  SessionManager.Sessions.Lock;   (on TUniServerModule.UniThreadTimer1Timer)

Because of :   SessionManager.Sessions.Lock;     

I remember a few days you solved it (on a precedent topic). Is this sample updated ? 

Thx.

Link to comment
Share on other sites

On 9/20/2021 at 12:03 PM, Abaksoft said:

Thank you IrigSoft,

When runing the appli I have an AV on :  SessionManager.Sessions.Lock;   (on TUniServerModule.UniThreadTimer1Timer)

Because of :   SessionManager.Sessions.Lock;     

I remember a few days you solved it (on a precedent topic). Is this sample updated ? 

Thx.

Yes it is.

this code is my real code on version 1524.

If You what try it without locking session.

Link to comment
Share on other sites

On 9/20/2021 at 12:03 PM, Abaksoft said:

Thank you IrigSoft,

When runing the appli I have an AV on :  SessionManager.Sessions.Lock;   (on TUniServerModule.UniThreadTimer1Timer)

Because of :   SessionManager.Sessions.Lock;     

I remember a few days you solved it (on a precedent topic). Is this sample updated ? 

Thx.

Hello @Abaksoft, did You succeed with my test case.

Link to comment
Share on other sites

  • 4 months later...
On 9/20/2021 at 11:03 AM, Abaksoft said:

Thank you IrigSoft,

When runing the appli I have an AV on :  SessionManager.Sessions.Lock;   (on TUniServerModule.UniThreadTimer1Timer)

Because of :   SessionManager.Sessions.Lock;     

I remember a few days you solved it (on a precedent topic). Is this sample updated ? 

Thx.

Hello!

How do you resolve this AV? 

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...