1

How to implement, each user has its own session timeout time

asked 2014-06-17 16:38:12 +0800

pjiang gravatar image pjiang
46 2

Hi, I am working on a feature that each user has its own session timeout value stored in DB and we should log user out after its own session time out time has reached.

I just have no idea where to start. Can somebody please give me some idea?

Thank you

delete flag offensive retag edit

3 Answers

Sort by ยป oldest newest most voted
1

answered 2014-06-17 20:12:42 +0800

chillworld gravatar image chillworld flag of Belgium
5367 4 9
https://github.com/chillw...

updated 2014-06-20 09:41:41 +0800

Hi there,

Quick thinking of me :
Create an abstract controller/viewmodel.
Get the timeout value from the authenticated user.
Set a timer with the timeout value.

If timer reaches tick => do logout.

Now you also need to set an actionlistener on you main component, so whenever you do an action, the timer is refreshed.
Don't forget to set the time out off in this case (or at max value for a user).

Edit :

As you can see I did not use the ZK Timer cause this will only work when the timer is attached to a page, witch is in this case not true.

Zk.xml

<listener>
    <description>ThreadLocal Synchronization Listener</description>
    <listener-class>be.chillworld.DesktopInitImpl
    </listener-class>
</listener>

DesktopInitImpl.java

package be.chillworld;

import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.util.DesktopInit;

/**
 *
 * @author cossaer.f
 */
public final class DesktopInitImpl implements DesktopInit {

    public DesktopInitImpl() {
    }

    public void init(Desktop dsktp, Object o) throws Exception {
        dsktp.addListener(new DesktopEventInterceptor(dsktp));
    }
}

DesktopEventInterceptor.java

package be.chillworld;

import java.util.Timer;
import java.util.TimerTask;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.EventInterceptor;

/**
 *
 * @author cossaer.f
 */
public class DesktopEventInterceptor implements EventInterceptor {

    private int userDelay = 10000;
    private Timer timer = new Timer();
    private final Desktop desktop;

    public DesktopEventInterceptor(Desktop desktop) {
        timer.schedule(new LogoutTask(), userDelay);
        this.desktop = desktop;
    }

    private void logout() {
        System.out.println("I DID A LOGOUT");
        // It could be that desktop.getSession().invalidate(); could do the trick also in stead of sendRedirect.
        // If session.invalidate works => no need to adding code to the viewmodel.
       try {
            Executions.activate(desktop);
        } catch (Exception ex) {
        }
        Executions.sendRedirect("www.google.be");
        Executions.deactivate(desktop);
    }

    private void resetTimer() {
        System.out.println("TIMER RESET to : " + userDelay);
        timer.cancel();
        timer = new Timer();
        timer.schedule(new LogoutTask(), userDelay);
    }

    public Event beforeSendEvent(Event event) {
        return event;
    }

    public Event beforePostEvent(Event event) {
        return event;
    }

    public Event beforeProcessEvent(Event event) {
        return event;
    }

    public void afterProcessEvent(Event event) {
        resetTimer();
    }

    private class LogoutTask extends TimerTask {

        public void run() {
            System.out.println("TIMER TICK");
            logout();
        }
    }
}

For the Executions to work we have to enable server-push.

In your indexViewModel :

 public IndexVm() {
    Executions.getCurrent().getDesktop().enableServerPush(true);
    // This won't work in the listener :(
    // I suggest create an abstractVM where you add an init method (annotation @init).
    // Put that line there and extend all your VM's to that abstractVM.
 }

Remove or change the logging to default logging of your project.
A debug level would be perfect here.

Greetz chill.

link publish delete flag offensive edit

Comments

Thank you. Can I use Timer from ZK? And any sample code for ab actionlistener?

pjiang ( 2014-06-18 16:37:50 +0800 )edit

I'll look into it tomorrow for your actionlistener. you could use the zk timer yes.

chillworld ( 2014-06-18 16:50:49 +0800 )edit

Thank you. I will start implementing the controller with timer. Looking forward to see your actionlistener.

pjiang ( 2014-06-18 17:08:06 +0800 )edit

Hi, Chillworld, your code works well. Whenever there is an Event coming in, the timer gets reset; Thank you! The only problem is I could not get hold of Executions or execution in this class, without which I could not send redirect to login page.

pjiang ( 2014-06-19 22:00:16 +0800 )edit

That I didn't test cause it was sample project without authentication. I'll investigate tomorrow (Desktop class has also getExecution so maybe pass the desktop to the desktopeventinterceptor)

chillworld ( 2014-06-19 22:15:40 +0800 )edit
1

answered 2014-07-07 03:45:14 +0800

cor3000 gravatar image cor3000
6280 2 7

updated 2014-07-07 03:56:15 +0800

Sorry for being late at the party, but isn't the obvious solution to just call and use the servlet container's functionality (maybe I am missing a detail but that's how I would do it): org.zkoss.zk.ui.http.SimpleSession.setMaxInactiveInterval(int)

This needs to be called only once when the user is determined (and his specific timeout is loaded from the DB) right after he logged in. Then no Timer and manual session eviction is required. To give the user instant feedback on the client side, that his session has timed out use the <automatic-timeout/> element.

If you need to call any specific logout code, you can do so in a SessionCleanup listener configured in zk.xml.

link publish delete flag offensive edit

Comments

Hey Cor, thx for that answer. Could you also provide that in the documentation here : http://books.zkoss.org/wiki/ZKDeveloper'sReference/UIPatterns/SessionTimeout_Management

chillworld ( 2014-07-07 11:26:49 +0800 )edit

I don't think this belongs there, as this section is about how to handle a session timeout, that already occurred at the client side in the UI, irrespective of what actually caused it (zk config, container config, programmatic session invalidation).

cor3000 ( 2014-07-08 00:59:28 +0800 )edit

I don't even think there is anything ZK specific about session timeout handling in contrast to the default servlet container specification, just a few convenience methods to delegate to the HttpSession object. ZK specific is that there are mechanisms to inform the front end about it automatically.

cor3000 ( 2014-07-08 01:04:11 +0800 )edit
0

answered 2014-06-17 18:05:37 +0800

mhj gravatar image mhj flag of Brazil
806 1 7

updated 2014-06-17 18:09:30 +0800

Hello young, regardless of whether the choice made is the best approach, there are many ways to check if time is over at DB. for example you can check every time you make a request if timeout was reached. Where i work user it has a key valid for day

link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
6 followers

RSS

Stats

Asked: 2014-06-17 16:38:12 +0800

Seen: 65 times

Last updated: Jul 07 '14

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More