B4J Question [ABMATERIAL] What's the best way to invalidate the session?

Cableguy

Expert
Licensed User
Longtime User
Hi guys

I'm trying to figure out how to invalidate a session after a predetermined elapsed time without user interaction...

Something like,
User starts webapp, and logs-in...
Does a few things, but then, for let's say 30mins, he takes no action on the webapp... Let's say he forgets the webapp logged-in and browser opened... Then if he, or someone else, decides to refresh or do something in the webapp, I need it to automatically return to the landing page to logs-in.

What's the best approach for this?
A global storing the last time the page was loaded and compare it to the "now" page load?
 

OliverA

Expert
Licensed User
Longtime User
Have you played with this public variable in ABMShared?
B4X:
Public SessionMaxInactiveIntervalSeconds As Int = 30*60 ' 30 minutes '1*60*24 ' one hour ' -1 = immortal but beware! This also means your cache is NEVER emptied!
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Yes I did, but from one of @alwaysbusy posts I read that, since the server (or the webapp, not sure which) send an heartbeat, the session stays alive... The session is only invalidated if no internet is available at the moment of the heartbeat.

So I need to manually invalidate it...
Unless I'm missing something...
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Brainstorming:
1) you keep last access time in session variable
a)In WebSocket_Connected, check last access time and if timed out, invalidate session and return to ./, otherwise update last access time to Now
b)In Page_ParseEvent, check last access time, invalidate session and return to ./, otherwise update last access time to Now
2) On top of that could also create a timer. This would allow you to proactively invalidate the session
a) In WebSocket_Connected, initialize timer
b) In Page_ParseEvent, reset timer
c) If timer executes, invalidate session and return to ./
Note: Make timer long enough in case page has some long running process it needs to complete
Note#2: The assumption for the above is that WebSocket_Connected and Page_ParseEvent are the only two entry points into your ABM Page. If any other entry points exists, they'll need to implement #1 and/or #2
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Brainstorming:
1) you keep last access time in session variable
a)In WebSocket_Connected, check last access time and if timed out, invalidate session and return to ./, otherwise update last access time to Now
b)In Page_ParseEvent, check last access time, invalidate session and return to ./, otherwise update last access time to Now
2) On top of that could also create a timer. This would allow you to proactively invalidate the session
a) In WebSocket_Connected, initialize timer
b) In Page_ParseEvent, reset timer
c) If timer executes, invalidate session and return to ./
Note: Make timer long enough in case page has some long running process it needs to complete
Note#2: The assumption for the above is that WebSocket_Connected and Page_ParseEvent are the only two entry points into your ABM Page. If any other entry points exists, they'll need to implement #1 and/or #2

This goes in-line with my idea and it may just work…
you mention page entry points… other than those mentioned, which other entry point can you imagine existing? ( I can only think of those two)
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
The upload handler calls Page_somethingsomething directly. IDK if that could be used as an entry point externally (outside of the upload handler) or if the upload handler could be abused to call up a page. Also, one could figure out the JS created by ABM and call the subs in your page directly via JS (circumventing Page_ParseEvent)
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
If I understand correctly, the upload handler is called at page level and returns to the same page, with the result from that particular operation… the subs are called on server side, and pages are served to the browser… the dynamic code is run in server side only… or am I still missing something?
Anyway, for now, I don't want to worry too much about that...
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I don't want to worry too much about that...
WebSocket_Connect and Page_ParseEvent should take care of 99.99% (or more) of the calls, so yes, time is well spent on them. With Authentication turned on, not even Page_ParseEvent becomes an entry point (you have to connect first!). The next thing to watch out for is for 3rd party custom components. They may call events in a page directly instead of using Page_ParseEvent. The issues I mentioned above depend on an already authenticated user being a bad actor (a knowledgeable bad actor).
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Implementation of Point 1a:

B4X:
    If session.GetAttribute("UserLastActionTime") = Null Then 'in first connection this is suposed to be null,
        session.setAttribute("UserLastActionTime", session.LastAccessedTime) ' so we set it to 'now'
    Else
        Dim SessionMaxInactiveIntervalSecondsInTicks As Int = (DateTime.TicksPerSecond * ABMShared.SessionMaxInactiveIntervalSeconds) 'This is Ticks convertion
    
        If (session.getAttribute("UserLastActionTime") + SessionMaxInactiveIntervalSecondsInTicks) < DateTime.Now Then
            session.Invalidate
            ABMShared.NavigateToPage(ws, ABMPageId, "../") 'Return to Landing Page
            Return
        Else
            session.setAttribute("UserLastActionTime", session.LastAccessedTime)
        End If
    End If

Point 1b does not seems needed, but I will keep testing as the page gets populated.

During the weekend I will add point 2
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
I ran into a similar situation as to this.

I have ABMaterial controlling a hardware device, and I need a per-user, per-session locking setup. So once one person was logged in, nobody else can get in until they either close the browser and it logs them out, or they walk away and disconnect, etc...

What I did was when the websocket gets booted for whatever reason (lost internet, walked away with phone in pocket, etc), I grab that persons session ID and throw it into a "to be killed" map and after certain period of time, I then invalidate the session and kill their cookie.
 
Upvote 0
Top