The two-step activation workflow¶
The two-step activation workflow, found in
django_registration.backends.activation
, implements a two-step registration
process: a user signs up, an inactive account is created, and an email is sent
containing an activation link which must be clicked to make the account active.
Behavior and configuration¶
A default URLconf is provided, which you can include()
in
your URL configuration; that URLconf is
django_registration.backends.activation.urls
. For example, to place user
registration under the URL prefix /accounts/
, you could place the following
in your root URLconf:
from django.urls import include, path
urlpatterns = [
# Other URL patterns ...
path('accounts/', include('django_registration.backends.activation.urls')),
path('accounts/', include('django.contrib.auth.urls')),
# More URL patterns ...
]
That also sets up the views from django.contrib.auth
(login, logout, password
reset, etc.).
This workflow makes use of up to three settings (click for details on each):
By default, this workflow uses
RegistrationForm
as its form class for user
registration; this can be overridden by passing the keyword argument
form_class
to the registration view.
Forms¶
- class django_registration.backends.activation.forms.ActivationForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)[source]¶
Form for the activation step of the two-step activation workflow.
This form has one field, the (string)
activation_key
, which should be an HMAC-signed activation-key value containing the username of the account to activate.
Views¶
Two views are provided to implement the signup/activation process. These subclass the base views of django-registration, so anything that can be overridden/customized there can equally be overridden/customized here. There are some additional customization points specific to this implementation, which are listed below.
For an overview of the templates used by these views (other than those specified below), and their context variables, see the quick start guide.
- class django_registration.backends.activation.views.RegistrationView(**kwargs)[source]¶
A subclass of
django_registration.views.RegistrationView
implementing the signup portion of this workflow.Important customization points unique to this class are:
- create_inactive_user(form)[source]¶
Creates and returns an inactive user account, and calls
send_activation_email()
to send the email with the activation key. The argumentform
is a valid registration form instance passed fromregister()
.- Parameters:
form (django_registration.forms.RegistrationForm) – The registration form.
- Return type:
- get_activation_key(user)[source]¶
Generates and returns the activation key which will be emailed to the user.
- Parameters:
user (django.contrib.auth.models.AbstractUser) – The new user account.
- Return type:
- get_email_context(activation_key)[source]¶
Returns a dictionary of values to be used as template context when generating the activation email.
- email_body_template¶
A string specifying the template to use for the body of the activation email. Default is
"django_registration/activation_email_body.txt"
.
- email_subject_template¶
A string specifying the template to use for the subject of the activation email. Default is
"django_registration/activation_email_subject.txt"
. Note that, to avoid header-injection vulnerabilities, the result of rendering this template will be forced into a single line of text, stripping newline characters.
- class django_registration.backends.activation.views.ActivationView(**kwargs)[source]¶
A subclass of
django_registration.views.ActivationView
implementing the activation portion of this workflow.This view expects to receive the activation key as the querystring parameter
activation_key
on the initial HTTPGET
; then it will populate that into anActivationForm
for re-submission in an HTTPPOST
request.If the activation key is missing, expired, or has an invalid signature, the form will have an error on the
activation_key
field.If the activation key has a valid non-expired signature, but account activation fails for another reason, the
activation_error
dictionary in the template context will contain acode
key with one of the following values:"already_activated"
Indicates the account has already been activated.
"bad_username"
Indicates the username decoded from the activation key is invalid (does not correspond to any user account).
How it works¶
When a user signs up, the activation workflow creates a new user instance to
represent the account, and sets the is_active
field to False
. It then
sends an email to the address provided during signup, containing a link to
activate the account. When the user clicks the link, the activation view sets
is_active
to True
, after which the user can log in.
The activation key is the username of the new account, signed using Django’s
cryptographic signing tools (specifically,
dumps()
is used, to produce a guaranteed-URL-safe
value). The activation process includes verification of the signature prior to
activation, as well as verifying that the user is activating within the
permitted window (as specified in the setting
ACCOUNT_ACTIVATION_DAYS
, mentioned above),
through use of Django’s TimestampSigner
.
Security considerations¶
The activation key emailed to the user in the activation workflow is a value obtained by using Django’s cryptographic signing tools. The activation key is of the form:
encoded_username:timestamp:signature
where encoded_username
is the username of the new account, timestamp
is the
timestamp of the time the user registered, and signature
is an HMAC of the
username and timestamp. The username and HMAC will be URL-safe base64 encoded;
the timestamp will be base62 encoded.
Django’s implementation uses the value of the
SECRET_KEY
setting as the key for
HMAC. Additionally, it permits the specification of a salt value which can be
used to “namespace” different uses of HMAC across a Django-powered site.
The activation workflow will use the value (a string) of the setting
REGISTRATION_SALT
as the salt, defaulting to the
string "registration"
if that setting is not specified. This value does not
need to be kept secret (only SECRET_KEY
does); it
serves only to ensure that other parts of a site which also produce signed
values from user input could not be used as a way to generate activation keys
for arbitrary usernames (and vice-versa).