summaryrefslogtreecommitdiff
path: root/docs/topics/auth.txt
diff options
context:
space:
mode:
authorJacob Kaplan-Moss <jacob@jacobian.org>2008-08-23 22:25:40 +0000
committerJacob Kaplan-Moss <jacob@jacobian.org>2008-08-23 22:25:40 +0000
commit97cb07c3a10ff0e584a260a7ee1001614691eb1d (patch)
tree204f4382c51e1c288dbf547875161731661733f5 /docs/topics/auth.txt
parentb3688e81943d6d059d3f3c95095498a5aab84852 (diff)
Massive reorganization of the docs. See the new docs online at http://docs.djangoproject.com/.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8506 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs/topics/auth.txt')
-rw-r--r--docs/topics/auth.txt1334
1 files changed, 1334 insertions, 0 deletions
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
new file mode 100644
index 0000000000..ca73b92ea8
--- /dev/null
+++ b/docs/topics/auth.txt
@@ -0,0 +1,1334 @@
+.. _topics-auth:
+
+=============================
+User authentication in Django
+=============================
+
+.. module:: django.contrib.auth
+ :synopsis: Django's authentication framework.
+
+Django comes with a user authentication system. It handles user accounts,
+groups, permissions and cookie-based user sessions. This document explains how
+things work.
+
+Overview
+========
+
+The auth system consists of:
+
+ * Users
+ * 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.
+ * Messages: A simple way to queue messages for given users.
+
+Installation
+============
+
+Authentication support is bundled as a Django application in
+``django.contrib.auth``. To install it, do the following:
+
+ 1. Put ``'django.contrib.auth'`` in your :setting:`INSTALLED_APPS` setting.
+ 2. Run the command ``manage.py syncdb``.
+
+Note that the default :file:`settings.py` file created by
+:djadmin:`django-admin.py startproject` includes ``'django.contrib.auth'`` in
+:setting:`INSTALLED_APPS` for convenience. If your :setting:`INSTALLED_APPS`
+already contains ``'django.contrib.auth'``, feel free to run
+:djadmin:`manage.py syncdb` again; you can run that command as many times as
+you'd like, and each time it'll only install what's needed.
+
+The :djadmin:`syncdb` command creates the necessary database tables, creates
+permission objects for all installed apps that need 'em, and prompts you to
+create a superuser account the first time you run it.
+
+Once you've taken those steps, that's it.
+
+Users
+=====
+
+.. class:: models.User
+
+API reference
+-------------
+
+Fields
+~~~~~~
+
+.. class:: models.User
+
+ :class:`~django.contrib.auth.models.User` objects have the following fields:
+
+ .. attribute:: models.User.username
+
+ Required. 30 characters or fewer. Alphanumeric characters only (letters,
+ digits and underscores).
+
+ .. attribute:: models.User.first_name
+
+ Optional. 30 characters or fewer.
+
+ .. attribute:: models.User.last_name
+
+ Optional. 30 characters or fewer.
+
+ .. attribute:: models.User.email
+
+ Optional. E-mail address.
+
+ .. attribute:: models.User.password
+
+ Required. A hash of, and metadata about, the password. (Django doesn't
+ store the raw password.) Raw passwords can be arbitrarily long and can
+ contain any character. See the "Passwords" section below.
+
+ .. attribute:: models.User.is_staff
+
+ Boolean. Designates whether this user can access the admin site.
+
+ .. attribute:: models.User.is_active
+
+ Boolean. Designates whether this account can be used to log in. Set this
+ flag to ``False`` instead of deleting accounts.
+
+ .. attribute:: models.User.is_superuser
+
+ Boolean. Designates that this user has all permissions without explicitly
+ assigning them.
+
+ .. attribute:: models.User.last_login
+
+ A datetime of the user's last login. Is set to the current date/time by
+ default.
+
+ .. attribute:: models.User.date_joined
+
+ A datetime designating when the account was created. Is set to the current
+ date/time by default when the account is created.
+
+Methods
+~~~~~~~
+
+.. class:: models.User
+
+ :class:`~django.contrib.auth.models.User` objects have two many-to-many
+ fields: models.User. ``groups`` and ``user_permissions``.
+ :class:`~django.contrib.auth.models.User` objects can access their related
+ objects in the same way as any other :ref:`Django model <topics-db-models>`:
+
+ .. code-block:: python
+
+ myuser.groups = [group_list]
+ myuser.groups.add(group, group, ...)
+ myuser.groups.remove(group, group, ...)
+ myuser.groups.clear()
+ myuser.user_permissions = [permission_list]
+ myuser.user_permissions.add(permission, permission, ...)
+ myuser.user_permissions.remove(permission, permission, ...)
+ myuser.user_permissions.clear()
+
+ In addition to those automatic API methods,
+ :class:`~django.contrib.auth.models.User` objects have the following custom
+ methods:
+
+ .. method:: models.User.is_anonymous()
+
+ Always returns ``False``. This is a way of differentiating
+ :class:`~django.contrib.auth.models.User` and
+ :class:`~django.contrib.auth.models.AnonymousUser` objects.
+ Generally, you should prefer using
+ :meth:`~django.contrib.auth.models.User.is_authenticated()` to this
+ method.
+
+ .. method:: models.User.is_authenticated()
+
+ Always returns ``True``. This is a way to
+ tell if the user has been authenticated. This does not imply any
+ permissions, and doesn't check if the user is active - it only indicates
+ that the user has provided a valid username and password.
+
+ .. method:: models.User.get_full_name()
+
+ Returns the :attr:`~django.contrib.auth.models.User.first_name` plus the
+ :attr:`~django.contrib.auth.models.User.last_name`,
+ with a space in between.
+
+ .. method:: models.User.set_password(raw_password)
+
+ Sets the user's password to the given raw string, taking care of the
+ password hashing. Doesn't save the
+ :class:`~django.contrib.auth.models.User` object.
+
+ .. method:: models.User.check_password(raw_password)
+
+ Returns ``True`` if the given raw string is the correct password for the
+ user. (This takes care of the password hashing in making the comparison.)
+
+ .. method:: models.User.set_unusable_password()
+
+ **New in Django development version.**
+ Marks the user as having no password set. This isn't the same as having
+ a blank string for a password.
+ :meth:`~django.contrib.auth.models.User.check_password()` for this user
+ will never return ``True``. Doesn't save the
+ :class:`~django.contrib.auth.models.User` object.
+
+ You may need this if authentication for your application takes place
+ against an existing external source such as an LDAP directory.
+
+ .. method:: models.User.has_usable_password()
+
+ **New in Django development version.**
+ Returns ``False`` if
+ :meth:`~django.contrib.auth.models.User.set_unusable_password()` has
+ been called for this user.
+
+ .. method:: models.User.get_group_permissions()
+
+ Returns a list of permission strings that the user has, through his/her
+ groups.
+
+ .. method:: models.User.get_all_permissions()
+
+ Returns a list of permission strings that the user has, both through group
+ and user permissions.
+
+ .. method:: models.User.has_perm(perm)
+
+ Returns ``True`` if the user has the specified permission, where perm is
+ in the format ``"package.codename"``. If the user is inactive, this method
+ will always return ``False``.
+
+ .. method:: models.User.has_perms(perm_list)
+
+ Returns ``True`` if the user has each of the specified permissions, where
+ each perm is in the format ``"package.codename"``. If the user is inactive,
+ this method will always return ``False``.
+
+ .. method:: models.User.has_module_perms(package_name)
+
+ Returns ``True`` if the user has any permissions in the given package (the
+ Django app label). If the user is inactive, this method will always return
+ ``False``.
+
+ .. method:: models.User.get_and_delete_messages()
+
+ Returns a list of :class:`~django.contrib.auth.models.Message` objects in
+ the user's queue and deletes the messages from the queue.
+
+ .. method:: models.User.email_user(subject, message, from_email=None)
+
+ Sends an e-mail to the user. If
+ :attr:`~django.contrib.auth.models.User.from_email` is ``None``, Django
+ uses the :setting:`DEFAULT_FROM_EMAIL`.
+
+ .. method:: models.User.get_profile()
+
+ Returns a site-specific profile for this user. Raises
+ :exc:`django.contrib.auth.models.SiteProfileNotAvailable` if the current
+ site doesn't allow profiles. For information on how to define a
+ site-specific user profile, see the section on
+ `storing additional user information`_ below.
+
+.. _storing additional user information: #storing-additional-information-about-users
+
+Manager functions
+~~~~~~~~~~~~~~~~~
+
+.. class:: models.UserManager
+
+ The :class:`~django.contrib.auth.models.User` model has a custom manager
+ that has the following helper functions:
+
+ .. method:: models.UserManager.create_user(username, email, password=None)
+
+ Creates, saves and returns a :class:`~django.contrib.auth.models.User`.
+ The :attr:`~django.contrib.auth.models.User.username`,
+ :attr:`~django.contrib.auth.models.User.email` and
+ :attr:`~django.contrib.auth.models.User.password` are set as given, and the
+ :class:`~django.contrib.auth.models.User` gets ``is_active=True``.
+
+ If no password is provided,
+ :meth:`~django.contrib.auth.models.User.set_unusable_password()` will be
+ called.
+
+ See `Creating users`_ for example usage.
+
+ .. method:: models.UserManager.make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
+
+ Returns a random password with the given length and given string of
+ allowed characters. (Note that the default value of ``allowed_chars``
+ doesn't contain letters that can cause user confusion, including ``1``,
+ ``I`` and ``0``).
+
+Basic usage
+-----------
+
+.. _topics-auth-creating-users:
+
+Creating users
+~~~~~~~~~~~~~~
+
+The most basic way to create users is to use the
+:meth:`~django.contrib.auth.models.UserManager.create_user` helper function
+that comes with Django::
+
+ >>> from django.contrib.auth.models import User
+ >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
+
+ # At this point, user is a User object that has already been saved
+ # to the database. You can continue to change its attributes
+ # if you want to change other fields.
+ >>> user.is_staff = True
+ >>> user.save()
+
+Changing passwords
+~~~~~~~~~~~~~~~~~~
+
+Change a password with :meth:`~django.contrib.auth.models.User.set_password()`::
+
+ >>> from django.contrib.auth.models import User
+ >>> u = User.objects.get(username__exact='john')
+ >>> u.set_password('new password')
+ >>> u.save()
+
+Don't set the :attr:`~django.contrib.auth.models.User.password` attribute
+directly unless you know what you're doing. This is explained in the next
+section.
+
+Passwords
+---------
+
+The :attr:`~django.contrib.auth.models.User.password` attribute of a
+:class:`~django.contrib.auth.models.User` object is a string in this format::
+
+ hashtype$salt$hash
+
+That's hashtype, salt and hash, separated by the dollar-sign character.
+
+Hashtype is either ``sha1`` (default), ``md5`` or ``crypt`` -- the algorithm
+used to perform a one-way hash of the password. Salt is a random string used
+to salt the raw password to create the hash. Note that the ``crypt`` method is
+only supported on platforms that have the standard Python ``crypt`` module
+available, and ``crypt`` support is only available in the Django development
+version.
+
+For example::
+
+ sha1$a1976$a36cc8cbf81742a8fb52e221aaeab48ed7f58ab4
+
+The :meth:`~django.contrib.auth.models.User.set_password` and
+:meth:`~django.contrib.auth.models.User.check_password` functions handle the
+setting and checking of these values behind the scenes.
+
+Previous Django versions, such as 0.90, used simple MD5 hashes without password
+salts. For backwards compatibility, those are still supported; they'll be
+converted automatically to the new style the first time
+:meth:`~django.contrib.auth.models.User.check_password()` works correctly for
+a given user.
+
+Anonymous users
+---------------
+
+.. class:: models.AnonymousUser
+
+ :class:`django.contrib.auth.models.AnonymousUser` is a class that
+ implements the :class:`django.contrib.auth.models.User` interface, with
+ these differences:
+
+ * :attr:`~django.contrib.auth.models.User.id` is always ``None``.
+ * :attr:`~django.contrib.auth.models.User.is_staff` and
+ :attr:`~django.contrib.auth.models.User.is_superuser` are always ``False``.
+ * :attr:`~django.contrib.auth.models.User.is_active` is always ``False``.
+ * :attr:`~django.contrib.auth.models.User.groups` and
+ :attr:`~django.contrib.auth.models.User.user_permissions` are always empty.
+ * :meth:`~django.contrib.auth.models.User.is_anonymous()` returns ``True``
+ instead of ``False``.
+ * :meth:`~django.contrib.auth.models.User.is_authenticated()` returns
+ ``False`` instead of ``True``.
+ * :meth:`~django.contrib.auth.models.User.has_perm()` always returns ``False``.
+ * :meth:`~django.contrib.auth.models.User.set_password()`,
+ :meth:`~django.contrib.auth.models.User.check_password()`,
+ :meth:`~django.contrib.auth.models.User.save()`,
+ :meth:`~django.contrib.auth.models.User.delete()`,
+ :meth:`~django.contrib.auth.models.User.set_groups()` and
+ :meth:`~django.contrib.auth.models.User.set_permissions()` raise
+ :exc:`NotImplementedError`.
+
+In practice, you probably won't need to use
+:class:`~django.contrib.auth.models.AnonymousUser` objects on your own, but
+they're used by Web requests, as explained in the next section.
+
+Creating superusers
+-------------------
+
+:djadmin:`manage.py syncdb <syncdb>` prompts you to create a superuser the first time
+you run it after adding ``'django.contrib.auth'`` to your
+:setting:`INSTALLED_APPS`. If you need to create a superuser at a later date,
+you can use a command line utility.
+
+**New in Django development version.**::
+
+ manage.py createsuperuser --username=joe --email=joe@example.com
+
+You will be prompted for a password. After you enter one, the user will be
+created immediately. If you leave off the :djadminopt:`--username` or the
+:djadminopt:`--email` options, it will prompt you for those values.
+
+If you're using an older release of Django, the old way of creating a superuser
+on the command line still works::
+
+ python /path/to/django/contrib/auth/create_superuser.py
+
+...where :file:`/path/to` is the path to the Django codebase on your
+filesystem. The ``manage.py`` command is preferred because it figures
+out the correct path and environment for you.
+
+.. _auth-profiles:
+
+Storing additional information about users
+------------------------------------------
+
+If you'd like to store additional information related to your users,
+Django provides a method to specify a site-specific related model --
+termed a "user profile" -- for this purpose.
+
+To make use of this feature, define a model with fields for the
+additional information you'd like to store, or additional methods
+you'd like to have available, and also add a
+:class:`~django.db.models.Field.ForeignKey` from your model to the
+:class:`~django.contrib.auth.models.User` model, specified with ``unique=True``
+to ensure only one instance of your model can be created for each
+:class:`~django.contrib.auth.models.User`.
+
+To indicate that this model is the user profile model for a given
+site, fill in the setting :setting:`AUTH_PROFILE_MODULE` with a string
+consisting of the following items, separated by a dot:
+
+1. The (normalized to lower-case) name of the application in which the
+ user profile model is defined (in other words, an all-lowercase
+ version of the name which was passed to
+ :djadmin:`manage.py startapp <startapp>` to create the application).
+
+2. The (normalized to lower-case) name of the model class.
+
+For example, if the profile model was a class named ``UserProfile``
+and was defined inside an application named ``accounts``, the
+appropriate setting would be::
+
+ AUTH_PROFILE_MODULE = 'accounts.userprofile'
+
+When a user profile model has been defined and specified in this
+manner, each :class:`~django.contrib.auth.models.User` object will have a
+method -- :class:`~django.contrib.auth.models.User.get_profile()`
+-- which returns the instance of the user profile model associated
+with that :class:`~django.contrib.auth.models.User`.
+
+For more information, see `Chapter 12 of the Django book`_.
+
+.. _Chapter 12 of the Django book: http://www.djangobook.com/en/1.0/chapter12/#cn222
+
+Authentication in Web requests
+==============================
+
+Until now, this document has dealt with the low-level APIs for manipulating
+authentication-related objects. On a higher level, Django can hook this
+authentication framework into its system of
+:class:`request objects <django.http.HttpRequest>`.
+
+First, install the
+:class:`~django.contrib.sessions.middleware.SessionMiddleware` and
+:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`
+middlewares by adding them to your :setting:`MIDDLEWARE_CLASSES` setting. See
+the :ref:`session documentation <topics-http-sessions>` for more information.
+
+Once you have those middlewares installed, you'll be able to access
+:attr:`request.user <django.http.HttpRequest.user>` in views.
+:attr:`request.user <django.http.HttpRequest.user>` will give you a
+:class:`~django.contrib.auth.models.User` object representing the currently
+logged-in user. If a user isn't currently logged in,
+:attr:`request.user <django.http.HttpRequest.user>` will be set to an instance
+of :class:`~django.contrib.auth.models.AnonymousUser` (see the previous
+section). You can tell them apart with
+:meth:`~django.contrib.auth.models.User.is_authenticated()`, like so::
+
+ if request.user.is_authenticated():
+ # Do something for authenticated users.
+ else:
+ # Do something for anonymous users.
+
+How to log a user in
+--------------------
+
+Django provides two functions in :mod:`django.contrib.auth`:
+:func:`~django.contrib.auth.authenticate()` and
+:func:`~django.contrib.auth.login()`.
+
+.. function:: authenticate()
+
+ To authenticate a given username and password, use
+ :func:`~django.contrib.auth.authenticate()`. It
+ takes two keyword arguments, ``username`` and ``password``, and it returns
+ a :class:`~django.contrib.auth.models.User` object if the password is
+ valid for the given username. If the password is invalid,
+ :func:`~django.contrib.auth.authenticate()` returns ``None``. Example::
+
+ from django.contrib.auth import authenticate
+ user = authenticate(username='john', password='secret')
+ if user is not None:
+ if user.is_active:
+ print "You provided a correct username and password!"
+ else:
+ print "Your account has been disabled!"
+ else:
+ print "Your username and password were incorrect."
+
+.. function:: login()
+
+ To log a user in, in a view, use :func:`~django.contrib.auth.login()`. It
+ takes an :class:`~django.http.HttpRequest` object and a
+ :class:`~django.contrib.auth.models.User` object.
+ :func:`~django.contrib.auth.login()` saves the user's ID in the session,
+ using Django's session framework, so, as mentioned above, you'll need to
+ make sure to have the session middleware installed.
+
+ This example shows how you might use both
+ :func:`~django.contrib.auth.authenticate()` and
+ :func:`~django.contrib.auth.login()`::
+
+ from django.contrib.auth import authenticate, login
+
+ def my_view(request):
+ username = request.POST['username']
+ password = request.POST['password']
+ user = authenticate(username=username, password=password)
+ if user is not None:
+ if user.is_active:
+ login(request, user)
+ # Redirect to a success page.
+ else:
+ # Return a 'disabled account' error message
+ else:
+ # Return an 'invalid login' error message.
+
+.. admonition:: Calling ``authenticate()`` first
+
+ When you're manually logging a user in, you *must* call
+ :func:`~django.contrib.auth.authenticate()` before you call
+ :func:`~django.contrib.auth.login()`.
+ :func:`~django.contrib.auth.authenticate()`
+ sets an attribute on the :class:`~django.contrib.auth.models.User` noting
+ which authentication backend successfully authenticated that user (see
+ the `backends documentation`_ for details), and this information is
+ needed later during the login process.
+
+.. _backends documentation: #other-authentication-sources
+
+Manually checking a user's password
+-----------------------------------
+
+.. function:: check_password()
+
+ If you'd like to manually authenticate a user by comparing a
+ plain-text password to the hashed password in the database, use the
+ convenience function :func:`django.contrib.auth.models.check_password`. It
+ takes two arguments: the plain-text password to check, and the full
+ value of a user's ``password`` field in the database to check against,
+ and returns ``True`` if they match, ``False`` otherwise.
+
+How to log a user out
+---------------------
+
+.. function:: logout()
+
+ To log out a user who has been logged in via
+ :func:`django.contrib.auth.login()`, use
+ :func:`django.contrib.auth.logout()` within your view. It takes an
+ :class:`~django.http.HttpRequest` object and has no return value.
+ Example::
+
+ from django.contrib.auth import logout
+
+ def logout_view(request):
+ logout(request)
+ # Redirect to a success page.
+
+ Note that :func:`~django.contrib.auth.logout()` doesn't throw any errors
+ if the user wasn't logged in.
+
+ **New in Django development version:** When you call
+ :func:`~django.contrib.auth.logout()`, the session
+ data for the current request is completely cleaned out. All existing data
+ is removed. This is to prevent another person from using the same web
+ browser to log in and have access to the previous user's session data.
+ If you want to put anything into the session that will be available to
+ the user immediately after logging out, do that *after* calling
+ :func:`django.contrib.auth.logout()`.
+
+Limiting access to logged-in users
+----------------------------------
+
+The raw way
+~~~~~~~~~~~
+
+The simple, raw way to limit access to pages is to check
+:meth:`request.user.is_authenticated()
+<django.contrib.auth.models.User.is_authenticated()>` and either redirect to a
+login page::
+
+ from django.http import HttpResponseRedirect
+
+ def my_view(request):
+ if not request.user.is_authenticated():
+ return HttpResponseRedirect('/login/?next=%s' % request.path)
+ # ...
+
+...or display an error message::
+
+ def my_view(request):
+ if not request.user.is_authenticated():
+ return render_to_response('myapp/login_error.html')
+ # ...
+
+The login_required decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. function:: decorators.login_required()
+
+ As a shortcut, you can use the convenient
+ :func:`~django.contrib.auth.decorators.login_required` decorator::
+
+ from django.contrib.auth.decorators import login_required
+
+ def my_view(request):
+ # ...
+ my_view = login_required(my_view)
+
+ Here's an equivalent example, using the more compact decorator syntax
+ introduced in Python 2.4::
+
+ from django.contrib.auth.decorators import login_required
+
+ @login_required
+ def my_view(request):
+ # ...
+
+ In the Django development version,
+ :func:`~django.contrib.auth.decorators.login_required` also takes an
+ optional ``redirect_field_name`` parameter. Example::
+
+ from django.contrib.auth.decorators import login_required
+
+ def my_view(request):
+ # ...
+ my_view = login_required(redirect_field_name='redirect_to')(my_view)
+
+ Again, an equivalent example of the more compact decorator syntax
+ introduced in Python 2.4::
+
+ from django.contrib.auth.decorators import login_required
+
+ @login_required(redirect_field_name='redirect_to')
+ def my_view(request):
+ # ...
+
+ :func:`~django.contrib.auth.decorators.login_required` does the following:
+
+ * If the user isn't logged in, redirect to
+ :setting:`settings.LOGIN_URL <LOGIN_URL>` (``/accounts/login/`` by
+ default), passing the current absolute URL in the query string as
+ ``next`` or the value of ``redirect_field_name``. For example:
+ ``/accounts/login/?next=/polls/3/``.
+
+ * If the user is logged in, execute the view normally. The view code
+ is free to assume the user is logged in.
+
+Note that you'll need to map the appropriate Django view to
+:setting:`settings.LOGIN_URL <LOGIN_URL>`. For example, using the defaults, add
+the following line to your URLconf::
+
+ (r'^accounts/login/$', 'django.contrib.auth.views.login'),
+
+.. function:: views.login()
+
+ Here's what ``django.contrib.auth.views.login`` does:
+
+ * If called via ``GET``, it displays a login form that POSTs to the same
+ URL. More on this in a bit.
+
+ * If called via ``POST``, it tries to log the user in. If login is
+ successful, the view redirects to the URL specified in ``next``. If
+ ``next`` isn't provided, it redirects to :setting:`settings.LOGIN_REDIRECT_URL <LOGIN_REDIRECT_URL>`
+ (which defaults to ``/accounts/profile/``). If login isn't successful,
+ it redisplays the login form.
+
+ It's your responsibility to provide the login form in a template called
+ ``registration/login.html`` by default. This template gets passed three
+ template context variables:
+
+ * ``form``: A :class:`~django.forms.Form` object representing the
+ login form. See the :ref:`forms documentation <topics-forms-index>`
+ for more on ``FormWrapper`` objects.
+
+ * ``next``: The URL to redirect to after successful login. This may contain
+ a query string, too.
+
+ * ``site_name``: The name of the current
+ :class:`~django.contrib.sites.models.Site``, according to the
+ :setting:`SITE_ID` setting. If you're using the Django development version
+ and you don't have the site framework installed, this will be set to the
+ value of ``request.META['SERVER_NAME']``. For more on sites, see
+ :ref:`ref-contrib-sites`.
+
+ If you'd prefer not to call the template :file:`registration/login.html`,
+ you can pass the ``template_name`` parameter via the extra arguments to
+ the view in your URLconf. For example, this URLconf line would use
+ :file:`myapp/login.html` instead::
+
+ (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
+
+ Here's a sample :file:`registration/login.html` template you can use as a
+ starting point. It assumes you have a :file:`base.html` template that
+ defines a ``content`` block::
+
+ {% extends "base.html" %}
+
+ {% block content %}
+
+ {% if form.errors %}
+ <p>Your username and password didn't match. Please try again.</p>
+ {% endif %}
+
+ <form method="post" action=".">
+ <table>
+ <tr><td>{{ form.username.label_tag }}</td><td>{{ form.username }}</td></tr>
+ <tr><td>{{ form.password.label_tag }}</td><td>{{ form.password }}</td></tr>
+ </table>
+
+ <input type="submit" value="login" />
+ <input type="hidden" name="next" value="{{ next }}" />
+ </form>
+
+ {% endblock %}
+
+ .. _forms documentation: ../forms/
+ .. _site framework docs: ../sites/
+
+Other built-in views
+--------------------
+
+In addition to the ``login`` view, the authentication system includes a
+few other useful built-in views:
+
+.. function:: django.contrib.auth.views.logout
+
+ Logs a user out.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to display after
+ logging the user out. This will default to
+ :file:`registration/logged_out.html` if no argument is supplied.
+
+ **Template context:**
+
+ * ``title``: The string "Logged out", localized.
+
+.. function:: django.contrib.auth.views.logout_then_login
+
+ Logs a user out, then redirects to the login page.
+
+ **Optional arguments:**
+
+ * ``login_url``: The URL of the login page to redirect to. This
+ will default to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not
+ supplied.
+
+.. function:: django.contrib.auth.views.password_change
+
+ Allows a user to change their password.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use for
+ displaying the password change form. This will default to
+ :file:`registration/password_change_form.html` if not supplied.
+
+ **Template context:**
+
+ * ``form``: The password change form.
+
+.. function:: django.contrib.auth.views.password_change_done
+
+ The page shown after a user has changed their password.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use. This will
+ default to :file:`registration/password_change_done.html` if not
+ supplied.
+
+.. function:: django.contrib.auth.views.password_reset
+
+ Allows a user to reset their password, and sends them the new password
+ in an e-mail.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use for
+ displaying the password reset form. This will default to
+ :file:`registration/password_reset_form.html` if not supplied.
+
+ * ``email_template_name``: The full name of a template to use for
+ generating the e-mail with the new password. This will default to
+ :file:`registration/password_reset_email.html` if not supplied.
+
+ **Template context:**
+
+ * ``form``: The form for resetting the user's password.
+
+.. function:: django.contrib.auth.views.password_reset_done
+
+ The page shown after a user has reset their password.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use. This will
+ default to :file:`registration/password_reset_done.html` if not
+ supplied.
+
+.. function:: django.contrib.auth.views.redirect_to_login
+
+ Redirects to the login page, and then back to another URL after a
+ successful login.
+
+ **Required arguments:**
+
+ * ``next``: The URL to redirect to after a successful login.
+
+ **Optional arguments:**
+
+ * ``login_url``: The URL of the login page to redirect to. This
+ will default to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not
+ supplied.
+
+Built-in forms
+---------------------
+
+If you don't want to use the built-in views, but want the convenience
+of not having to write forms for this functionality, the authentication
+system provides several built-in forms:
+
+ * :class:`django.contrib.auth.forms.AdminPasswordChangeForm`: A form used
+ in the admin interface to change a user's password.
+
+ * :class:`django.contrib.auth.forms.AuthenticationForm`: A form for
+ logging a user in.
+
+ * :class:`django.contrib.auth.forms.PasswordChangeForm`: A form for
+ allowing a user to change their password.
+
+ * :class:`django.contrib.auth.forms.PasswordResetForm`: A form for
+ resetting a user's password and e-mailing the new password to them.
+
+ * :class:`django.contrib.auth.forms.UserCreationForm`: A form for creating
+ a new user.
+
+Limiting access to logged-in users that pass a test
+---------------------------------------------------
+
+To limit access based on certain permissions or some other test, you'd do
+essentially the same thing as described in the previous section.
+
+The simple way is to run your test on
+:attr:`request.user <django.http.HttpRequest.user>` in the view directly.
+For example, this view checks to make sure the user is logged in and has the
+permission ``polls.can_vote``::
+
+ def my_view(request):
+ if not (request.user.is_authenticated() and request.user.has_perm('polls.can_vote')):
+ return HttpResponse("You can't vote in this poll.")
+ # ...
+
+.. function:: decorators.user_passes_test()
+
+ As a shortcut, you can use the convenient ``user_passes_test`` decorator::
+
+ from django.contrib.auth.decorators import user_passes_test
+
+ def my_view(request):
+ # ...
+ my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view)
+
+ We're using this particular test as a relatively simple example. However,
+ if you just want to test whether a permission is available to a user, you
+ can use the :func:`django.contrib.auth.decorators.permission_required()`
+ decorator, described later in this document.
+
+ Here's the same thing, using Python 2.4's decorator syntax::
+
+ from django.contrib.auth.decorators import user_passes_test
+
+ @user_passes_test(lambda u: u.has_perm('polls.can_vote'))
+ def my_view(request):
+ # ...
+
+ :func:`~django.contrib.auth.decorators.user_passes_test` takes a required
+ argument: a callable that takes a
+ :class:`~django.contrib.auth.models.User` object and returns ``True`` if
+ the user is allowed to view the page. Note that
+ :func:`~django.contrib.auth.decorators.user_passes_test` does not
+ automatically check that the :class:`~django.contrib.auth.models.User` is
+ not anonymous.
+
+ :func:`~django.contrib.auth.decorators.user_passes_test()` takes an
+ optional ``login_url`` argument, which lets you specify the URL for your
+ login page (:setting:`settings.LOGIN_URL <LOGIN_URL>` by default).
+
+ Example in Python 2.3 syntax::
+
+ from django.contrib.auth.decorators import user_passes_test
+
+ def my_view(request):
+ # ...
+ my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')(my_view)
+
+ Example in Python 2.4 syntax::
+
+ from django.contrib.auth.decorators import user_passes_test
+
+ @user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')
+ def my_view(request):
+ # ...
+
+The permission_required decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. function:: decorators.permission_required()
+
+ It's a relatively common task to check whether a user has a particular
+ permission. For that reason, Django provides a shortcut for that case: the
+ :func:`~django.contrib.auth.decorators.permission_required()` decorator.
+ Using this decorator, the earlier example can be written as::
+
+ from django.contrib.auth.decorators import permission_required
+
+ def my_view(request):
+ # ...
+ my_view = permission_required('polls.can_vote')(my_view)
+
+ Note that :func:`~django.contrib.auth.decorators.permission_required()`
+ also takes an optional ``login_url`` parameter. Example::
+
+ from django.contrib.auth.decorators import permission_required
+
+ def my_view(request):
+ # ...
+ my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)
+
+ As in the ``login_required`` decorator, ``login_url`` defaults to
+ :setting:`settings.LOGIN_URL <LOGIN_URL>`.
+
+Limiting access to generic views
+--------------------------------
+
+To limit access to a :ref:`generic view <ref-generic-views>`, write a thin
+wrapper around the view, and point your URLconf to your wrapper instead of the
+generic view itself. For example::
+
+ from django.views.generic.date_based import object_detail
+
+ @login_required
+ def limited_object_detail(*args, **kwargs):
+ return object_detail(*args, **kwargs)
+
+Permissions
+===========
+
+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 are set globally per type of object, not per specific object
+instance. For example, it's possible to say "Mary may change news stories," but
+it's not currently possible to say "Mary may change news stories, but only the
+ones she created herself" or "Mary may only change news stories that have a
+certain status, publication date or ID." The latter functionality is something
+Django developers are currently discussing.
+
+Default permissions
+-------------------
+
+When ``django.contrib.auth`` is listed in your :setting:`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 when you run
+:djadmin:`manage.py syncdb <syncdb>`; the first time you run ``syncdb`` after
+adding ``django.contrib.auth`` to :setting:`INSTALLED_APPS`, the default
+permissions will be created for all previously-installed models, as well as
+for any new models being installed at that time. Afterward, it will create
+default permissions for new models each time you run
+:djadmin:`manage.py syncdb <syncdb>`.
+
+.. _custom-permissions:
+
+Custom permissions
+------------------
+
+To create custom permissions for a given model object, use the ``permissions``
+:ref:`model Meta attribute <meta-options>`.
+
+This example model creates three custom permissions::
+
+ class USCitizen(models.Model):
+ # ...
+ class Meta:
+ permissions = (
+ ("can_drive", "Can drive"),
+ ("can_vote", "Can vote in elections"),
+ ("can_drink", "Can drink alcohol"),
+ )
+
+The only thing this does is create those extra permissions when you run
+:djadmin:`manage.py syncdb <syncdb>`.
+
+API reference
+-------------
+
+.. class:: models.Permission
+
+ Just like users, permissions are implemented in a Django model that lives in
+ `django/contrib/auth/models.py`_.
+
+.. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py
+
+Fields
+~~~~~~
+
+:class:`~django.contrib.auth.models.Permission` objects have the following
+fields:
+
+.. attribute:: models.Permission.name
+
+ Required. 50 characters or fewer. Example: ``'Can vote'``.
+
+.. attribute:: models.Permission.content_type
+
+ Required. A reference to the ``django_content_type`` database table,
+ which contains a record for each installed Django model.
+
+.. attribute:: models.Permission.codename
+
+ Required. 100 characters or fewer. Example: ``'can_vote'``.
+
+Methods
+~~~~~~~
+
+:class:`~django.contrib.auth.models.Permission` objects have the standard
+data-access methods like any other :ref:`Django model <ref-models-instances>`.
+
+Authentication data in templates
+================================
+
+The currently logged-in user and his/her permissions are made available in the
+:ref:`template context <ref-templates-api>` when you use
+:class:`~django.template.context.RequestContext`.
+
+.. admonition:: Technicality
+
+ Technically, these variables are only made available in the template context
+ if you use :class:`~django.template.context.RequestContext` *and* your
+ :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting contains
+ ``"django.core.context_processors.auth"``, which is default. For more, see
+ the :ref:`RequestContext docs <subclassing-context-requestcontext>`.
+
+Users
+-----
+
+The currently logged-in user, either a
+:class:`~django.contrib.auth.models.User` instance or an
+:class:`~django.contrib.auth.models.AnonymousUser` instance, is stored in the
+template variable ``{{ user }}``::
+
+ {% if user.is_authenticated %}
+ <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
+ {% else %}
+ <p>Welcome, new user. Please log in.</p>
+ {% endif %}
+
+Permissions
+-----------
+
+The currently logged-in user's permissions are stored in the template variable
+``{{ perms }}``. This is an instance of
+:class:`django.core.context_processors.PermWrapper`, which is a
+template-friendly proxy of permissions.
+
+In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
+:meth:`User.has_module_perms <django.contrib.auth.models.User.has_module_perms>`.
+This example would display ``True`` if the logged-in user had any permissions
+in the ``foo`` app::
+
+ {{ perms.foo }}
+
+Two-level-attribute lookup is a proxy to
+:meth:`User.has_perm <django.contrib.auth.models.User.has_perm>`. This example
+would display ``True`` if the logged-in user had the permission
+``foo.can_vote``::
+
+ {{ perms.foo.can_vote }}
+
+Thus, you can check permissions in template ``{% if %}`` statements::
+
+ {% if perms.foo %}
+ <p>You have permission to do something in the foo app.</p>
+ {% if perms.foo.can_vote %}
+ <p>You can vote!</p>
+ {% endif %}
+ {% if perms.foo.can_drive %}
+ <p>You can drive!</p>
+ {% endif %}
+ {% else %}
+ <p>You don't have permission to do anything in the foo app.</p>
+ {% endif %}
+
+Groups
+======
+
+Groups 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 e-mail
+messages.
+
+Messages
+========
+
+The message system is a lightweight way to queue messages for given users.
+
+A message is associated with a :class:`~django.contrib.auth.models.User`.
+There's no concept of expiration or timestamps.
+
+Messages are used by the Django admin after successful actions. For example,
+``"The poll Foo was created successfully."`` is a message.
+
+The API is simple:
+
+.. method:: models.User.message_set.create(message)
+
+ To create a new message, use
+ ``user_obj.message_set.create(message='message_text')``.
+
+ To retrieve/delete messages, use
+ :meth:`user_obj.get_and_delete_messages() <django.contrib.auth.models.User.get_and_delete_messages>`,
+ which returns a list of ``Message`` objects in the user's queue (if any)
+ and deletes the messages from the queue.
+
+In this example view, the system saves a message for the user after creating
+a playlist::
+
+ def create_playlist(request, songs):
+ # Create the playlist with the given songs.
+ # ...
+ request.user.message_set.create(message="Your playlist was added successfully.")
+ return render_to_response("playlists/create.html",
+ context_instance=RequestContext(request))
+
+When you use :class:`~django.template.context.RequestContext`, the currently
+logged-in user and his/her messages are made available in the
+:ref:`template context <ref-templates-api>` as the template variable
+``{{ messages }}``. Here's an example of template code that displays messages::
+
+ {% if messages %}
+ <ul>
+ {% for message in messages %}
+ <li>{{ message }}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+
+Note that :class:`~django.template.context.RequestContext` calls
+:meth:`~django.contrib.auth.models.User.get_and_delete_messages` behind the
+scenes, so any messages will be deleted even if you don't display them.
+
+Finally, note that this messages framework only works with users in the user
+database. To send messages to anonymous users, use the
+:ref:`session framework <topics-http-sessions>`.
+
+.. _authentication-backends:
+
+Other authentication sources
+============================
+
+The authentication that comes with Django is good enough for most common cases,
+but you may have the need to hook into another authentication source -- that
+is, another source of usernames and passwords or authentication methods.
+
+For example, your company may already have an LDAP setup that stores a username
+and password for every employee. It'd be a hassle for both the network
+administrator and the users themselves if users had separate accounts in LDAP
+and the Django-based applications.
+
+So, to handle situations like this, the Django authentication system lets you
+plug in another authentication sources. You can override Django's default
+database-based scheme, or you can use the default system in tandem with other
+systems.
+
+Specifying authentication backends
+----------------------------------
+
+Behind the scenes, Django maintains a list of "authentication backends" that it
+checks for authentication. When somebody calls
+:func:`django.contrib.auth.authenticate()` -- as described in "How to log a
+user in" above -- Django tries authenticating across all of its authentication
+backends. If the first authentication method fails, Django tries the second
+one, and so on, until all backends have been attempted.
+
+The list of authentication backends to use is specified in the
+:setting:`AUTHENTICATION_BACKENDS` setting. This should be a tuple of Python
+path names that point to Python classes that know how to authenticate. These
+classes can be anywhere on your Python path.
+
+By default, :setting:`AUTHENTICATION_BACKENDS` is set to::
+
+ ('django.contrib.auth.backends.ModelBackend',)
+
+That's the basic authentication scheme that checks the Django users database.
+
+The order of :setting:`AUTHENTICATION_BACKENDS` matters, so if the same username
+and password is valid in multiple backends, Django will stop processing at the
+first positive match.
+
+Writing an authentication backend
+---------------------------------
+
+An authentication backend is a class that implements two methods:
+``get_user(user_id)`` and ``authenticate(**credentials)``.
+
+The ``get_user`` method takes a ``user_id`` -- which could be a username,
+database ID or whatever -- and returns a ``User`` object.
+
+The ``authenticate`` method takes credentials as keyword arguments. Most of
+the time, it'll just look like this::
+
+ class MyBackend:
+ def authenticate(self, username=None, password=None):
+ # Check the username/password and return a User.
+
+But it could also authenticate a token, like so::
+
+ class MyBackend:
+ def authenticate(self, token=None):
+ # Check the token and return a User.
+
+Either way, ``authenticate`` should check the credentials it gets, and it
+should return a ``User`` object that matches those credentials, if the
+credentials are valid. If they're not valid, it should return ``None``.
+
+The Django admin system is tightly coupled to the Django ``User`` object
+described at the beginning of this document. For now, the best way to deal with
+this is to create a Django ``User`` object for each user that exists for your
+backend (e.g., in your LDAP directory, your external SQL database, etc.) You
+can either write a script to do this in advance, or your ``authenticate``
+method can do it the first time a user logs in.
+
+Here's an example backend that authenticates against a username and password
+variable defined in your ``settings.py`` file and creates a Django ``User``
+object the first time a user authenticates::
+
+ from django.conf import settings
+ from django.contrib.auth.models import User, check_password
+
+ class SettingsBackend:
+ """
+ Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.
+
+ Use the login name, and a hash of the password. For example:
+
+ ADMIN_LOGIN = 'admin'
+ ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
+ """
+ def authenticate(self, username=None, password=None):
+ login_valid = (settings.ADMIN_LOGIN == username)
+ pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
+ if login_valid and pwd_valid:
+ try:
+ user = User.objects.get(username=username)
+ except User.DoesNotExist:
+ # Create a new user. Note that we can set password
+ # to anything, because it won't be checked; the password
+ # from settings.py will.
+ user = User(username=username, password='get from settings.py')
+ user.is_staff = True
+ user.is_superuser = True
+ user.save()
+ return user
+ return None
+
+ def get_user(self, user_id):
+ try:
+ return User.objects.get(pk=user_id)
+ except User.DoesNotExist:
+ return None
+
+Handling authorization in custom backends
+-----------------------------------------
+
+Custom auth backends can provide their own permissions.
+
+The user model will delegate permission lookup functions
+(:meth:`~django.contrib.auth.models.User.get_group_permissions()`,
+:meth:`~django.contrib.auth.models.User.get_all_permissions()`,
+:meth:`~django.contrib.auth.models.User.has_perm()`, and
+:meth:`~django.contrib.auth.models.User.has_module_perms()`) to any
+authentication backend that implements these functions.
+
+The permissions given to the user will be the superset of all permissions
+returned by all backends. That is, Django grants a permission to a user that
+any one backend grants.
+
+The simple backend above could implement permissions for the magic admin
+fairly simply::
+
+ class SettingsBackend:
+
+ # ...
+
+ def has_perm(self, user_obj, perm):
+ if user_obj.username == settings.ADMIN_LOGIN:
+ return True
+ else:
+ return False
+
+This gives full permissions to the user granted access in the above example.
+Notice that the backend auth functions all take the user object as an argument,
+and they also accept the same arguments given to the associated
+:class:`django.contrib.auth.models.User` functions.
+
+A full authorization implementation can be found in
+`django/contrib/auth/backends.py`_, which is the default backend and queries
+the ``auth_permission`` table most of the time.
+
+.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py