multifactor.common¶
Utility functions used internally by the decorator, mixins, and factor views.
You can import any of these from multifactor.common; they form the
package’s de-facto public helper API. Source: multifactor/common.py.
has_multifactor¶
has_multifactor(request: HttpRequest) -> bool
True if request.user has at least one UserKey with enabled=True.
Cheap — runs UserKey.objects.filter(...).exists(). Use in templates or
views to gate “you should add a factor” prompts.
active_factors¶
active_factors(request: HttpRequest) -> list[tuple]
Returns the list of currently-active factors in
request.session["multifactor"], filtering out any whose recheck_expiry
has passed. Each tuple is (key_type, key_id, verified_at, recheck_expiry).
Side-effect: writes the filtered list back to the session so expired entries don’t accumulate.
from multifactor.common import active_factors
if not active_factors(request):
# user is logged in but has no verified factors right now
...
disabled_fallbacks¶
disabled_fallbacks(request: HttpRequest) -> QuerySet[str]
Flat values list of DisabledFallback.fallback for the current user. Used
by factors.fallback.Auth to skip transports the user has opted out of.
next_check¶
next_check() -> float
Returns a Unix timestamp now + randint(RECHECK_MIN, RECHECK_MAX). Called
by write_session() to set each factor’s recheck_expiry.
render¶
render(request, template_name, context, **kwargs) -> HttpResponse
A thin wrapper around django.shortcuts.render with the context spread
into a fresh dict. Used by the views; you’re unlikely to need it directly.
method_url¶
method_url(method: str) -> str
Maps a factor name to its auth URL name:
method_url("FIDO2") # -> "multifactor:fido2_auth"
method_url("TOTP") # -> "multifactor:totp_auth"
write_session¶
write_session(request: HttpRequest, key: UserKey | None) -> None
Records a successful factor verification in the session. Prepends a new
tuple (key_type, key_id, now, next_check_or_False) to
request.session["multifactor"], removing any prior entry for the same
key (so duplicates don’t accumulate).
If key is None (the fallback case), the tuple is (None, None, now, next_check).
If key is a real UserKey, also updates key.last_used and saves.
from multifactor.common import write_session
# after your own custom factor verification logic
write_session(request, key=my_userkey)
login¶
login(request: HttpRequest) -> HttpResponse
Post-verification redirect. Order of precedence:
If
MULTIFACTOR["SHOW_LOGIN_MESSAGE"]is truthy, flashesLOGIN_MESSAGEformatted with the URL ofmultifactor:home.If
session["multifactor-next"]is set, redirects there (and pops it).If
MULTIFACTOR["LOGIN_CALLBACK"]is set, callsimport_string(callback)(request, username=session["base_username"])and returns the result.Otherwise redirects to
settings.LOGIN_URL.
is_bypassed¶
is_bypassed(request: HttpRequest) -> bool
Returns the result of import_string(MULTIFACTOR["BYPASS"])(request),
or False if BYPASS is unset. See conditional bypass.
See also¶
Session model — how these are used.
Authentication flow — the call-graph.