Ending an APM session when browser tab is closed
Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’.
Short Description
Ending an APM session when a user is closing the browser tab.
Problem solved by this Code Snippet
Sometimes an user stops using an application delivered via APM by closing the browsers tab. When this happens it's most likely that the APM session remains active until it times out. In general this shouldn't be a problem, but in some specfic situations ending the active APM session when the browser tab is closed may be required. This will force the browser to enter the APM policy from scratch when reconnecting to the APM delivered application.
How to use this Code Snippet
This code snipet is an iRule which uses the STREAM-profile. This iRule will inject a little bit of JavaScript that will interact with the F5 BIG-IP to determine if the active APM session needs to be terminated.
NB: Please note that this solution which is using the beforeunload event will probably not work for mobile platforms. See: Don't lose user and app state, use Page Visibility - igvita.com
Code Snippet Meta Information
- Version: 1.0
- Coding Language: Tcl / JavaScript
Full Code Snippet
when CLIENT_ACCEPTED {
ACCESS::restrict_irule_events enable
}
when HTTP_REQUEST {
# Disable the stream filter by default
STREAM::disable
# LTM does not uncompress response content, so if the server has compression enabled
# and it cannot be disabled on the server, we can prevent the server from
# sending a compressed response by removing the compression offerings from the client
HTTP::header remove "Accept-Encoding"
# don't terminate an active session (a page reload will set this variable to 0 again)
ACCESS::session data set session.custom.terminate_session 0
if { [HTTP::uri] starts_with "/f5/remove_session" } {
log local0. "DEBUG: received request to terminate session"
ACCESS::session data set session.custom.terminate_session 1
after 1000 {
# this session can be terminated if still inactive for 1000 ms
if { [ACCESS::session data get session.custom.terminate_session] eq 1 } {
log local0. "DEBUG: terminate_session"
ACCESS::session modify -sid [ACCESS::session sid] -timeout 1
}
}
}
set uri [HTTP::uri]
}
when HTTP_RESPONSE {
if { ([HTTP::header "Content-Type"] starts_with "text/html") && not ($uri starts_with "/saml/") } {
STREAM::expression {@</title>@</title>
<script type="text/javascript">
if ('sendBeacon' in navigator) {
window.addEventListener('beforeunload', function() {
navigator.sendBeacon(
'/f5/remove_session',
'All your base are belong to us');
}, false);
}
</script>@}
STREAM::enable
}
unset uri
}