A significant percentage of modern, interactive websites allow some form of user interaction – from allowing simple comments on a blog, to full editorial control of articles on a news site. If a site offers any sort of ecommerce, authentication and authorization of paying customers is essential.
Just managing users – lost usernames, forgotten passwords and keeping information up to date – can be a real pain. As a programmer, writing an authentication system can be even worse.
Lucky for us, Django provides a default implementation for managing user accounts, groups, permissions and cookie-based user sessions out of the box.
Like most things in Django, the default implementation is fully extensible and customizable to suit your project’s needs. So let’s jump right in.
The Django authentication system handles both authentication and authorization. Briefly, authentication verifies a user is who they claim to be, and authorization determines what an authenticated user is allowed to do. Here the term authentication is used to refer to both tasks.
The authentication system consists of:
- Permissions: Binary (yes/no) flags designating whether a user may perform a certain task
- Groups: A generic way of applying labels and permissions to more than one user
- A configurable password hashing system
- Forms for managing user authentication and authorization
- View tools for logging in users, or restricting content
- A pluggable backend system
The authentication system in Django aims to be very generic and doesn’t provide some features commonly found in web authentication systems. Solutions for some of these common problems have been implemented in third-party packages:
- Password strength checking
- Throttling of login attempts
- Authentication against third-parties (OAuth, for example)
Using The Django Authentication System
Django’s authentication system in its default configuration has evolved to serve the most common project needs, handling a reasonably wide range of tasks, and has a careful implementation of passwords and permissions. For projects where authentication needs differ from the default, Django also supports extensive extension and customization of authentication.
User objects are the core of the authentication system. They typically represent the people interacting with your site and are used to enable things like restricting access, registering user profiles, associating content with creators etc. Only one class of user exists in Django’s authentication framework, i.e.,
superusers or admin
staff users are just user objects with special attributes set, not different classes of user objects. The primary attributes of the default user are:
Create superusers using the
You will be prompted for a password. After you enter one, the user will be created immediately. If you leave off the
--username or the
The simplest, and least error prone way to create and manage users is through the Django admin. Django also provides built in views and forms to allow users to log in and out and change their own password. We will be looking at user management via the admin and generic user forms a bit later in this chapter, but first, let’s look at how we would handle user authentication directly.
The most direct way to create users is to use the included
create_user() helper function:
Django does not store raw (clear text) passwords on the user model, but only a hash. Because of this, do not attempt to manipulate the password attribute of the user directly. This is why a helper function is used when creating a user. To change a user’s password, you have two options:
manage.py changepassword usernameoffers a method of changing a User’s password from the command line. It prompts you to change the password of a given user which you must enter twice. If they both match, the new password will be changed immediately. If you do not supply a user, the command will attempt to change the password of the user whose username matches the current system user.
- You can also change a password programmatically, using
Changing a user’s password will log out all their sessions if the
SessionAuthenticationMiddleware is enabled.
Permissions and Authorization
Django comes with a simple permissions system. It provides a way to assign permissions to specific users and groups of users. It’s used by the Django admin site, but you’re welcome to use it in your own code. The Django admin site uses permissions as follows:
- Access to view the “add” form and add an object is limited to users with the “add” permission for that type of object.
- Access to view the change list, view the “change” form and change an object is limited to users with the “change” permission for that type of object.
- Access to delete an object is limited to users with the “delete” permission for that type of object.
Permissions can be set not only per type of object, but also per specific object instance. By using the
has_delete_permission() methods provided by the
ModelAdmin class, it’s possible to customize permissions for different object instances of the same type.
User objects have two many-to-many fields:
User objects can access their related objects in the same way as any other Django model.
django.contrib.auth is listed in your
INSTALLED_APPS setting, it will ensure that three default permissions – add, change and delete – are created for each Django model defined in one of your installed applications. These permissions will be created for all new models each time you run
django.contrib.auth.models.Group models are a generic way of categorizing users so you can apply permissions, or some other label, to those users. A user can belong to any number of groups. A user in a group automatically has the permissions granted to that group. For example, if the group
Site editors has the permission
can_edit_home_page, any user in that group will have that permission.
Beyond permissions, groups are a convenient way to categorize users to give them some label, or extended functionality. For example, you could create a group “
Special users,” and you could write code that could, say, give them access to a members-only portion of your site, or send them members-only email messages.
Programmatically Creating Permissions
While custom permissions can be defined within a model’s
Meta class, you can also create permissions directly. For example, you can create the
can_publish permission for a
BookReview model in
The permission can then be assigned to a
User via its
user_permissions attribute or to a
Group via its
ModelBackend caches permissions on the
User object after the first time they need to be fetched for a permissions check. This is typically fine for the request-response cycle since permissions are not typically checked immediately after they are added (in the admin, for example).
If you are adding permissions and checking them immediately afterward, in a test or view for example, the easiest solution is to re-fetch the
User from the database. For example: