Multi-Factor Authentication
Multi-Factor Authentication (MFA) system for enhanced security.
Models
- class auth_kit.mfa.models.MFAMethod(*args, **kwargs)
Bases:
ModelMulti-Factor Authentication method configuration for users.
Stores MFA method configuration including method name (e.g., ‘app’, ‘email’), TOTP secret keys, backup codes, and status flags. Each method can be marked as primary (the default method) and active/inactive. Enforces constraints ensuring only one primary method per user and that primary methods must be active.
- Constraints:
Unique (user, name) combination
Only one primary method per user
Primary methods must be active
- Parameters:
id (BigAutoField) – Primary key: ID
name (CharField) – Name. MFA method name (e.g., ‘app’, ‘email’)
secret (CharField) – Secret. TOTP secret key for generating verification codes
is_primary (BooleanField) – Is primary. Whether this is the user’s primary MFA method
is_active (BooleanField) – Is active. Whether this method is active and can be used
_backup_codes (JSONField) – Backup codes. JSON field storing backup codes for account recovery
Relationship fields:
- Parameters:
user (
ForeignKeytoUser) – User. User who owns this MFA method (related name:mfa_methods)
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- id: int | None
Type:
BigAutoFieldPrimary key: ID
A wrapper for a deferred-loading field. When the value is read from this
- is_active
Type:
BooleanFieldIs active. Whether this method is active and can be used
A wrapper for a deferred-loading field. When the value is read from this
- is_primary
Type:
BooleanFieldIs primary. Whether this is the user’s primary MFA method
A wrapper for a deferred-loading field. When the value is read from this
- name
Type:
CharFieldName. MFA method name (e.g., ‘app’, ‘email’)
A wrapper for a deferred-loading field. When the value is read from this
- objects: ClassVar[MFAMethodManager] = <auth_kit.mfa.models.MFAMethodManager object>
- secret
Type:
CharFieldSecret. TOTP secret key for generating verification codes
A wrapper for a deferred-loading field. When the value is read from this
- user
Type:
ForeignKeytoUserUser. User who owns this MFA method (related name:
mfa_methods)Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
- class auth_kit.mfa.models.MFAMethodManager(*args, **kwargs)
Bases:
ManagerManager for MFAMethod model providing convenience methods for MFA operations.
Provides methods for retrieving MFA methods by name, checking primary methods, and creating methods with backup codes.
- check_method(user_id: int | str, method_name: str, is_active: bool = True) None
Verify that a method exists for user.
- Parameters:
user_id – User identifier
method_name – MFA method name to check
is_active – Filter by active status
- Raises:
MFAMethodDoesNotExistError – If method not found
- create_with_backup_codes(**kwargs: Any) tuple[MFAMethod, set[str]]
Create MFA method with generated backup codes.
- Parameters:
**kwargs – Additional fields for method creation
- Returns:
Tuple of (created method, raw backup codes)
- get_by_name(user_id: int | str, name: str, is_active: bool = True) MFAMethod
Retrieve MFA method by user and method name.
- Parameters:
user_id – User identifier
name – MFA method name
is_active – Filter by active status
- Returns:
MFA method instance
- Raises:
MFAMethodDoesNotExistError – If method not found
- get_primary_active(user_id: Any) MFAMethod
Retrieve user’s primary active MFA method.
- Parameters:
user_id – User identifier
- Returns:
Primary active MFA method
- Raises:
MFAMethodDoesNotExistError – If no primary active method found
Views
Login Views
- class auth_kit.mfa.views.LoginFirstStepView(**kwargs: Any)
Bases:
LoginViewFirst step of MFA-enabled authentication.
Validates user credentials and initiates MFA flow if enabled. Returns either ephemeral token for MFA verification or complete authentication tokens if MFA is disabled for the user.
- authentication_classes = []
- get_serializer_class() type[Serializer]
Get first step serializer class.
- Returns:
Combined serializer for credential validation and MFA initiation
- permission_classes = (<class 'rest_framework.permissions.AllowAny'>,)
- post(request: Request, *args: Any, **kwargs: Any) Response
Process first step authentication.
- Parameters:
request – HTTP request with credentials
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response with ephemeral token or complete authentication
- throttle_scope = 'auth_kit'
- class auth_kit.mfa.views.LoginSecondStepView(**kwargs: Any)
Bases:
LoginViewSecond step of MFA authentication.
Verifies MFA code and ephemeral token to complete authentication. Returns full authentication tokens upon successful verification.
- authentication_classes = []
- get_serializer_class() type[Serializer]
Get second step serializer class.
- Returns:
Combined serializer for MFA verification and token generation
- permission_classes = (<class 'rest_framework.permissions.AllowAny'>,)
- post(request: Request, *args: Any, **kwargs: Any) Response
Process second step MFA verification.
- Parameters:
request – HTTP request with ephemeral token and verification code
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response with authentication tokens
- throttle_scope = 'auth_kit'
- class auth_kit.mfa.views.LoginChangeMethodView(**kwargs)
Bases:
GenericAPIViewChange MFA method during authentication flow.
Allows users to switch to a different MFA method during login using their ephemeral token from first step authentication.
- authentication_classes = []
- permission_classes = (<class 'rest_framework.permissions.AllowAny'>,)
- post(request: Request, *args: Any, **kwargs: Any) Response
Switch to different MFA method.
- Parameters:
request – HTTP request with ephemeral token and new method
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response with new ephemeral token for selected method
- serializer_class
alias of
MFAChangeMethodSerializer
- throttle_scope = 'auth_kit'
- class auth_kit.mfa.views.LoginMFAResendView(**kwargs)
Bases:
GenericAPIViewResend MFA verification code during authentication.
Allows users to request a new verification code for methods that support code dispatch (e.g., email) using their ephemeral token.
- authentication_classes = []
- permission_classes = (<class 'rest_framework.permissions.AllowAny'>,)
- post(request: Request, *args: Any, **kwargs: Any) Response
Resend verification code.
- Parameters:
request – HTTP request with ephemeral token
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response with new ephemeral token
- serializer_class
alias of
MFAResendSerializer
- throttle_scope = 'auth_kit'
MFA Management Views
- class auth_kit.mfa.views.MFAMethodViewSet(**kwargs)
Bases:
CreateModelMixin,ListModelMixin,GenericViewSetViewSet for managing user MFA methods.
Provides endpoints for listing available methods, creating new methods, confirming setup, managing activation status, and method deletion. All operations require authentication and operate on current user’s methods.
- Actions:
list: Get all available MFA methods with setup status
create: Initialize new MFA method with backup codes
confirm: Activate newly created method with verification
deactivate: Deactivate active non-primary method
primary: Set method as primary for user
send: Send verification code for testing
delete: Permanently remove MFA method
- confirm(request: Request, *args: Any, **kwargs: Any) Response
Confirm and activate newly created MFA method.
- Parameters:
request – HTTP request with method name and verification code
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response confirming method activation
- create(request: Request, *args: Any, **kwargs: Any) Response
Create a new MFA method for the user.
- Parameters:
request – HTTP request with method configuration
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response with created method details and backup codes
- deactivate(request: Request, *args: Any, **kwargs: Any) Response
Deactivate active MFA method.
- Parameters:
request – HTTP request with method name and verification code
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response confirming method deactivation
- delete(request: Request, *args: Any, **kwargs: Any) Response
Permanently delete MFA method.
- Parameters:
request – HTTP request with method name and optional verification code
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Empty response with 204 status
- get_queryset() Any
Get queryset filtered to current user’s MFA methods.
- Returns:
QuerySet of user’s MFA methods
- get_serializer_class() type[Any]
Get appropriate serializer class based on action.
- Returns:
Serializer class for current action
- list(request: Request, *args: Any, **kwargs: Any) Response
List all available MFA methods with user’s setup status.
- Parameters:
request – HTTP request
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response with method configurations and status
- pagination_class = None
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)
- primary(request: Request, *args: Any, **kwargs: Any) Response
Set MFA method as primary for user.
- Parameters:
request – HTTP request with method name and optional primary code
*args – Variable length argument list
**kwargs – Arbitrary keyword arguments
- Returns:
Response confirming primary method update
Serializers
Login Serializers
- auth_kit.mfa.serializers.login.get_mfa_first_step_serializer() type[Serializer]
Get combined serializer for first step MFA authentication.
Combines login request serializer with MFA first step response serializer to handle credential validation and MFA initiation.
- Returns:
Combined serializer class for first step authentication
- auth_kit.mfa.serializers.login.get_mfa_second_step_serializer() type[Serializer]
Get combined serializer for second step MFA authentication.
Combines MFA verification request serializer with login response serializer to handle code verification and token generation.
- Returns:
Combined serializer class for second step authentication
- class auth_kit.mfa.serializers.login_factors.MFAFirstStepResponseSerializer(*args, **kwargs)
Bases:
SerializerSerializer for first step MFA authentication response.
Returns ephemeral token and method information for MFA verification, or complete authentication response if MFA is disabled for user.
- ephemeral_token
Temporary token for MFA verification
- method
Selected MFA method name
- mfa_enabled
Boolean indicating if MFA is required
- class auth_kit.mfa.serializers.login_factors.MFASecondStepRequestSerializer(*args, **kwargs)
Bases:
SerializerSerializer for second step MFA verification request.
Validates ephemeral token and verification code to complete authentication.
- ephemeral_token
Token from first step authentication
- code
MFA verification code (TOTP or backup code)
- class auth_kit.mfa.serializers.login_factors.MFAChangeMethodSerializer(*args, **kwargs)
Bases:
SerializerSerializer for changing MFA method during authentication.
Allows switching to a different MFA method using valid ephemeral token.
- ephemeral_token
Current ephemeral token
- new_method
Name of new MFA method to switch to
- validate(attrs: MFAChangeMethodAttrs) MFAChangeMethodAttrs
Validate method change request and generate new ephemeral token.
- Parameters:
attrs – Input attributes dictionary
- Returns:
Validated attributes with new ephemeral token
- Raises:
ValidationError – If token is invalid or same method selected
MFA Management Serializers
- class auth_kit.mfa.serializers.mfa.MFAMethodConfigSerializer(*args, **kwargs)
Bases:
SerializerSerializer for MFA method configuration display.
Shows method status and setup information for management interfaces.
- name
MFA method name
- is_active
Whether method is active
- is_primary
Whether method is set as primary
- is_setup
Whether method has been configured by user
- class auth_kit.mfa.serializers.mfa.MFAMethodConfirmSerializer(*args, **kwargs)
Bases:
MFAMethodGenericSerializerSerializer for confirming and activating new MFA methods.
Validates TOTP code and activates the method. Sets as primary if no other primary method exists.
- method
MFA method name to confirm
- code
TOTP verification code
- class auth_kit.mfa.serializers.mfa.MFAMethodCreateSerializer(*args, **kwargs)
Bases:
MFAMethodGenericSerializerSerializer for creating new MFA methods.
Initializes a new MFA method with backup codes and setup instructions. Method must be confirmed before activation.
- method
MFA method name to create
- backup_codes
Generated backup codes for the method
- setup_data
Method-specific setup data (e.g., QR code)
- create(validated_data: dict[str, Any]) dict[str, Any]
Create new MFA method with backup codes and setup data.
- Parameters:
validated_data – Validated input data
- Returns:
Dictionary with method data, backup codes, and setup instructions
- detail = None
- class auth_kit.mfa.serializers.mfa.MFAMethodDeactivateSerializer(*args, **kwargs)
Bases:
MFAMethodGenericSerializerSerializer for deactivating active MFA methods.
Deactivates non-primary MFA methods after code verification. Primary methods cannot be deactivated directly.
- method
MFA method name to deactivate
- code
TOTP verification code
- class auth_kit.mfa.serializers.mfa.MFAMethodDeleteSerializer(*args, **kwargs)
Bases:
MFAMethodGenericSerializerSerializer for deleting MFA methods.
Permanently removes MFA method. Behavior controlled by settings for deleting active/primary methods and requiring verification codes.
- method
MFA method name to delete
- code
Verification code (conditional based on settings)
- class auth_kit.mfa.serializers.mfa.MFAMethodPrimaryUpdateSerializer(*args, **kwargs)
Bases:
MFAMethodGenericSerializerSerializer for setting MFA method as primary.
Updates the primary method designation. Optionally requires verification from current primary method based on settings.
- method
MFA method name to set as primary
- primary_code
Verification code from current primary method (optional)
- class auth_kit.mfa.serializers.mfa.MFAMethodSendCodeSerializer(*args, **kwargs)
Bases:
MFAMethodGenericSerializerSerializer for sending verification codes to MFA methods.
Triggers code dispatch for methods that support it (e.g., email). Useful for testing method configuration.
- method
MFA method name to send code to
Handlers
Base Handler
- class auth_kit.mfa.handlers.base.MFABaseHandler(mfa_method: MFAMethod)
Bases:
objectBase class for all MFA method handlers.
Provides common functionality for TOTP generation/validation, backup code management, and code dispatch. Subclasses must implement method-specific behavior like sending codes via email or SMS.
Subclasses must define a NAME (snake_case method identifier) and optionally customize DISPLAY_NAME (human-readable name), REQUIRES_DISPATCH flag for code sending, SETUP_RESPONSE_MESSAGE for user feedback, and TOTP timing parameters (TOTP_INTERVAL and TOTP_VALID_WINDOW). Each handler instance is associated with an MFAMethod instance.
- DISPLAY_NAME = ''
- NAME = ''
- REQUIRES_DISPATCH = True
- TOTP_INTERVAL = 30
- TOTP_VALID_WINDOW = 0
- __init__(mfa_method: MFAMethod) None
Initialize handler with MFA method.
- Parameters:
mfa_method – MFAMethod instance to handle
- classmethod get_initialize_method_serializer_class() type[Serializer]
Get serializer class for method setup responses.
- Returns:
Serializer class for setup responses
- initialize_method() dict[str, Any]
Initialize method setup and return setup data.
- Returns:
Dictionary with setup information
- validate_backup_code(backup_code: str) bool
Validate and consume backup code.
- Parameters:
backup_code – Backup code to validate
- Returns:
True if code is valid and consumed
Email Handler
- class auth_kit.mfa.handlers.email.MFAEmailHandler(mfa_method: MFAMethod)
Email-based MFA handler.
Sends TOTP verification codes to user’s email address. Uses longer TOTP intervals to account for email delivery delays.
- DISPLAY_NAME = 'EMAIL'
- EMAIL_HTML_TEMPLATE = 'auth_kit/mfa/email/code.html'
- EMAIL_PLAIN_TEMPLATE = 'auth_kit/mfa/email/code.txt'
- EMAIL_SUBJECT = 'Your verification code'
- NAME = 'email'
- TOTP_INTERVAL = 180
App Handler
- class auth_kit.mfa.handlers.app.MFAAppHandler(mfa_method: MFAMethod)
Authenticator app-based MFA handler.
Generates QR codes and provisioning URIs for setting up TOTP in authenticator applications. Does not require code dispatch as codes are generated locally on user’s device.
- APPLICATION_ISSUER_NAME = 'MyApplication'
- DISPLAY_NAME = 'APP'
- NAME = 'app'
- REQUIRES_DISPATCH = False
Services
Backup Codes Service
- auth_kit.mfa.services.backup_codes.generate_backup_codes(num_of_codes: int, code_length: int, allowed_chars: str) set[str]
Generate a set of unique backup codes.
Creates cryptographically secure backup codes using Django’s random string generator with specified character set.
- Parameters:
num_of_codes – Number of backup codes to generate
code_length – Length of each backup code
allowed_chars – Character set for code generation
- Returns:
Set of unique backup code strings
User Token Service
- class auth_kit.mfa.services.user_token.EphemeralTokenService
Bases:
objectService for managing ephemeral tokens in MFA authentication flow.
Provides secure token generation and validation with time-based expiry and user/method binding to prevent token misuse and replay attacks.
- Class Attributes:
KEY_SALT: Salt for HMAC token generation SECRET: Secret key for token signing EXPIRY_TIME: Token validity duration in seconds
- EXPIRY_TIME = 900
- KEY_SALT = 'auth_kit.mfa.utils.UserTokenGenerator'
- SECRET = 'this-is-a-mock-secret-key'
- check_token(token: str) tuple[User, str] | None
Validate and decode ephemeral token.
Verifies token signature, expiry time, and extracts user and method information from valid tokens.
- Parameters:
token – Ephemeral token string to validate
- Returns:
Tuple of (user, method_name) if valid, None if invalid
- make_token(user: User, mfa_method_name: str) str
Generate ephemeral token for user and MFA method.
Creates a time-limited token that binds user identity with specific MFA method for secure state management.
- Parameters:
user – User instance for token generation
mfa_method_name – MFA method name to bind to token
- Returns:
Signed ephemeral token string
- auth_kit.mfa.services.user_token.ephemeral_token_service = <auth_kit.mfa.services.user_token.EphemeralTokenService object>
Service for managing ephemeral tokens in MFA authentication flow.
Provides secure token generation and validation with time-based expiry and user/method binding to prevent token misuse and replay attacks.
- Class Attributes:
KEY_SALT: Salt for HMAC token generation SECRET: Secret key for token signing EXPIRY_TIME: Token validity duration in seconds
Utilities
- auth_kit.mfa.utils.get_setup_data_schemas() list[type[Serializer]]
Get serializer classes for all handler dispatch messages.
Used for generating polymorphic OpenAPI schemas that show different response formats for various MFA method types.
- Returns:
List of serializer classes for method setup responses
- auth_kit.mfa.utils.get_mfa_login_first_step_response_schemas() list[type[Serializer]]
Get serializer classes for MFA login first step responses.
Returns both MFA-enabled and no-MFA response serializers for OpenAPI schema generation.
- Returns:
List of serializer classes for first step login responses
Exceptions
- exception auth_kit.mfa.exceptions.MFAMethodDoesNotExistError
Bases:
ValidationErrorException raised when requested MFA method does not exist.
Used when attempting to access, validate, or manage an MFA method that is not found in the database for the specified user.
- detail
Human-readable error message
- code
Machine-readable error code
Settings
- class auth_kit.mfa.mfa_settings.MFASetting
Default MFA settings configuration for Auth Kit.
Provides all configurable options for MFA functionality including handler configuration, security settings, view/serializer classes, and behavioral constraints.
- GET_NO_MFA_LOGIN_RESPONSE_SERIALIZER: Callable[[], type[Serializer]] = 'auth_kit.mfa.serializers.login_factors.get_no_mfa_login_response_serializer'
- LOGIN_CHANGE_METHOD_VIEW: type[LoginChangeMethodView] = 'auth_kit.mfa.views.LoginChangeMethodView'
- LOGIN_FIRST_STEP_VIEW: type[LoginFirstStepView] = 'auth_kit.mfa.views.LoginFirstStepView'
- LOGIN_MFA_METHOD_VIEW_SET: type[MFAMethodViewSet] = 'auth_kit.mfa.views.MFAMethodViewSet'
- LOGIN_MFA_RESEND_VIEW: type[LoginMFAResendView] = 'auth_kit.mfa.views.LoginMFAResendView'
- LOGIN_SECOND_STEP_VIEW: type[LoginSecondStepView] = 'auth_kit.mfa.views.LoginSecondStepView'
- MFA_CHANGE_METHOD_SERIALIZER: type[MFAChangeMethodSerializer] = 'auth_kit.mfa.serializers.login_factors.MFAChangeMethodSerializer'
- MFA_FIRST_STEP_RESPONSE_SERIALIZER: type[MFAFirstStepResponseSerializer] = 'auth_kit.mfa.serializers.login_factors.MFAFirstStepResponseSerializer'
- MFA_FIRST_STEP_SERIALIZER_FACTORY: Callable[[], type[Serializer]] = 'auth_kit.mfa.serializers.login.get_mfa_first_step_serializer'
- MFA_HANDLERS: list[type[MFABaseHandler]] = ['auth_kit.mfa.handlers.app.MFAAppHandler', 'auth_kit.mfa.handlers.email.MFAEmailHandler']
- MFA_METHOD_CONFIG_SERIALIZER: type[MFAMethodConfigSerializer] = 'auth_kit.mfa.serializers.mfa.MFAMethodConfigSerializer'
- MFA_METHOD_CONFIRM_SERIALIZER: type[MFAMethodConfirmSerializer] = 'auth_kit.mfa.serializers.mfa.MFAMethodConfirmSerializer'
- MFA_METHOD_CREATE_SERIALIZER: type[MFAMethodCreateSerializer] = 'auth_kit.mfa.serializers.mfa.MFAMethodCreateSerializer'
- MFA_METHOD_DEACTIVATE_SERIALIZER: type[MFAMethodDeactivateSerializer] = 'auth_kit.mfa.serializers.mfa.MFAMethodDeactivateSerializer'
- MFA_METHOD_DELETE_SERIALIZER: type[MFAMethodDeleteSerializer] = 'auth_kit.mfa.serializers.mfa.MFAMethodDeleteSerializer'
- MFA_METHOD_PRIMARY_UPDATE_SERIALIZER: type[MFAMethodPrimaryUpdateSerializer] = 'auth_kit.mfa.serializers.mfa.MFAMethodPrimaryUpdateSerializer'
- MFA_METHOD_SEND_CODE_SERIALIZER: type[MFAMethodSendCodeSerializer] = 'auth_kit.mfa.serializers.mfa.MFAMethodSendCodeSerializer'
- MFA_RESEND_SERIALIZER: type[MFAResendSerializer] = 'auth_kit.mfa.serializers.login_factors.MFAResendSerializer'
- MFA_SECOND_STEP_REQUEST_SERIALIZER: type[MFASecondStepRequestSerializer] = 'auth_kit.mfa.serializers.login_factors.MFASecondStepRequestSerializer'