Restricting front-end session time

Hi all!

I’d like to restrict the session time for users who are logged into the front end of a MODX website.

I’ve experimented with session_cookie_lifetime and session_gc_maxlifetime - but I’ve not seen any change in behaviour even when setting these to very short durations.

And presumably those settings would affect Manager sessions too?

Would be grateful for any thoughts!

MODX 3.0.4-pl | PHP 8.3

You should be able to do it with a plugin attached to OnWebAuthentication and a snippet call placed in every front-end template.

In the plugin, you’d set a $_SESSION variable with the current time.

In the snippet, you’d read that variable, and use the current time to calculate the elapsed time. If it’s over the limit, you’d forward the user to a page displaying a “Sorry, your time is up” message.

You might also want to use a hook in the Login snippet to do something similar, but using the user’s last login time instead of the $_SESSION variable (which would be gone at that point). Otherwise, the user could just log out and log in again to defeat your system.

Many thanks, Bob.

I’ve employed similar tactics to this in non-MODX custom apps in the past - so I’ll take a look and let you know how I get on.

Thinking about this further - I’ll want to kick users out of the site precisely at the end of the session time [not just when they next click a link] so I think I’ll need to add a javascript timer / redirect as well.

Still curious about the session_cookie_lifetime and session_gc_maxlifetime system settings. Are they still used by MODX? I couldn’t see any change even in the Manager session time when changing these.

Thanks again.

“session_gc_maxlifetime” is for the “garbage collection” time (gc). That determines how long session info is kept in MODX sessions table before getting deleted. Without garbage collection, the sessions table gets huge over time.

As long as you’re using MODX sessions (“session_handler_class” set to “modSessionHandler”), “session_cookie_lifetime” should determine how long some can stay logged in.

Thanks for the input @snowcreative :+1:

What you say is really how I understood it, I think - I just don’t see it happening in practice.

Here’s an example - If I set the session_cookie_lifetime to 60 seconds …

And then, clear the cache and log out - I get an updated time on the Keep me logged in checkbox

But when I log in [whether I check Keep me logged in or not] - wait for five minutes, ten minutes, an hour etc - I can still continue to browse the Manager.

What am I missing?

OK, here’s what’s going on. When you log in, a cookie gets set. It has no expiration time, so once you’re logged in, you’re logged in until you log out or quit your browser. The “remember me” checkbox OVERRIDES this behavior, so what you set there makes your browser remember your login info, so that when you go back to the site after quitting your browser, the cookie is not deleted until the expiration date/time is reached. This also, however, makes the cookie expire at a specific point in time, so if you set “session_cookie_lifetime” to a short time, like 30 minutes (or 1 minute), then you’ll be kicked out of the manager at that time.

At least, that’s the way it works in MODX 2.8.

HOWEVER, there seems to be a bug in 3.0, and no expiration time is getting set when you click the “remember me” checkbox. Does anyone know if there was some intention to change how manager session cookie management happens in 3.0?

In any case, it is a little confusing the way this works (at least in 2.8). Shouldn’t there be a separate setting for how long someone remains logged in once they log in? “Remember me” seems more designed to retain the cookie beyond the current editing session, over a period of days or weeks, not to shorten the time people can stay logged in.

:+1: thanks again … glad I’m not going mad!

I just filed a bug report.

1 Like

See the github thread I referenced above for a fix. Editing one line of code (changing the triple equal sign to a double one) makes “remember me” work.

1 Like

Hi folks - had a quick look at this today - here’s my initial solution to automatically log front-end users out after a set period of time.

The requirement for this is based around the fact that pages on the site contain sensitive information so I don’t want front-end users to have endless sessions. Later, I’ll add a javascript timer too so that we don’t need to wait until the user clicks a link before being logged out - but this version is probably most relevant to MODX.

I’d be happy to hear any comments / improvements.


It works as two plugins:

auto-logout-initiate
Runs at OnWebLogin and sets initial $_SESSION['last-activity'] time

<?php

// auto-logout-initiate | OnWebLogin | Add initial $_SESSION['last-activity'] on user login

// New session - update last activity time
$_SESSION['last-activity'] = time();

auto-logout
Runs at OnWebPagePrerender and logs the user out if they try to reach a page after the timeout has expired

<?php

// auto-logout | OnWebPagePrerender | Automatically logs front-end users out after a set period of time

// Set the session timeout period (in seconds)
$timeout = 1800; 

// Get this resource
$thisResource = $modx->resource;

// Set a comma-separated list of your Resource Groups that you want to add auto-logout to
$protectedGroups = array("Protected Pages", "Some Other Group");

$isProtected = false;

if ($thisResource->isMember($protectedGroups)) {
        $isProtected = true;
}

if ($isProtected) { // Only check protected pages
    
    $lastActivityTime = isset($_SESSION['last-activity']) ? $_SESSION['last-activity'] : 0;
    
    // Check if $lastActivityTime is set and not equal to 0
    if ($lastActivityTime !== 0) {
        
        // Calculate the time difference
        $timeElapsed = time() - $lastActivityTime;

        // Check if the session has timed out
        if ($timeElapsed > $timeout) {
            // Log the user out
            header("Location: login?service=logout");
        } else {
            // Session is still valid, update last activity time
            $_SESSION['last-activity'] = time();
        }
            
    } else {
        
        // $lastActivityTime is not set or is equal to 0
        $_SESSION['last-activity'] = null;
        // Log the user out
        header("Location: login?service=logout");
    }
  
}