Session Policies

RobustAuth gives you full control over how many concurrent sessions a user is allowed to have. Configure via the SESSION_POLICY setting.


"multi" (default)

No restrictions. A user can have unlimited active sessions simultaneously — one per device, browser, or app install.

ROBUST_AUTH = {
    "SESSION_POLICY": "multi",
}

Use case: Most APIs, mobile apps, SaaS platforms where users legitimately log in from many devices.


"single"

Only one active session is allowed per user at any time. When a new login occurs, all existing sessions are immediately revoked before the new one is created.

ROBUST_AUTH = {
    "SESSION_POLICY": "single",
}

Use case: Banking-style applications, high-security dashboards, or apps where you want to prevent shared account access.

The forced_logout event is recorded in LoginHistory for every session revoked this way.


"max_count"

At most MAX_SESSIONS active sessions are allowed per user. When a new login would exceed this limit, behaviour depends on REVOKE_OLDEST_ON_LIMIT:

With REVOKE_OLDEST_ON_LIMIT = True (default)

The oldest session is automatically revoked to make room for the new one.

ROBUST_AUTH = {
    "SESSION_POLICY": "max_count",
    "MAX_SESSIONS": 3,
    "REVOKE_OLDEST_ON_LIMIT": True,
}

With REVOKE_OLDEST_ON_LIMIT = False

The login is rejected with a ValueError and the session_limit_reached signal fires. You handle it — for example, by returning a 403 with a message asking the user to log out from another device.

ROBUST_AUTH = {
    "SESSION_POLICY": "max_count",
    "MAX_SESSIONS": 5,
    "REVOKE_OLDEST_ON_LIMIT": False,
}
# Handle in your login view or via signal
from robustauth import signals
from django.dispatch import receiver

@receiver(signals.session_limit_reached)
def handle_limit(sender, user, active_sessions, **kwargs):
    # notify user, return custom error, etc.
    pass

Use case: Streaming services, team tools, or apps that want to limit device count without being as strict as "single".


Comparison

Policy

New login behaviour

Existing sessions

multi

Always allowed

Untouched

single

Always allowed

All revoked

max_count + revoke oldest

Always allowed

Oldest revoked if over limit

max_count + no auto-revoke

Rejected if over limit

Untouched


Password Change Behaviour

Regardless of session policy, when REVOKE_ON_PASSWORD_CHANGE = True (default), all sessions except the current one are revoked when a user changes their password. Call SessionManager.on_password_change() from your password change view:

from robustauth.session_manager import SessionManager

def change_password(request):
    user.set_password(new_password)
    user.save()
    SessionManager.on_password_change(user, current_session=request.auth.session)