123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173 |
- =============================
- User authentication in Django
- =============================
- 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 ``INSTALLED_APPS`` setting.
- 2. Run the command ``manage.py syncdb``.
- Note that the default ``settings.py`` file created by
- ``django-admin.py startproject`` includes ``'django.contrib.auth'`` in
- ``INSTALLED_APPS`` for convenience. If your ``INSTALLED_APPS`` already contains
- ``'django.contrib.auth'``, feel free to run ``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 ``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
- =====
- Users are represented by a standard Django model, which lives in
- `django/contrib/auth/models.py`_.
- .. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py
- API reference
- -------------
- Fields
- ~~~~~~
- ``User`` objects have the following fields:
- * ``username`` -- Required. 30 characters or fewer. Alphanumeric characters
- only (letters, digits and underscores).
- * ``first_name`` -- Optional. 30 characters or fewer.
- * ``last_name`` -- Optional. 30 characters or fewer.
- * ``email`` -- Optional. E-mail address.
- * ``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.
- * ``is_staff`` -- Boolean. Designates whether this user can access the
- admin site.
- * ``is_active`` -- Boolean. Designates whether this account can be used
- to log in. Set this flag to ``False`` instead of deleting accounts.
- * ``is_superuser`` -- Boolean. Designates that this user has all permissions
- without explicitly assigning them.
- * ``last_login`` -- A datetime of the user's last login. Is set to the
- current date/time by default.
- * ``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
- ~~~~~~~
- ``User`` objects have two many-to-many fields: ``groups`` and
- ``user_permissions``. ``User`` objects can access their related
- objects in the same way as any other `Django model`_::
- 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, ``User`` objects have the following
- custom methods:
- * ``is_anonymous()`` -- Always returns ``False``. This is a way of
- differentiating ``User`` and ``AnonymousUser`` objects. Generally, you
- should prefer using ``is_authenticated()`` to this method.
- * ``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.
- * ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``,
- with a space in between.
- * ``set_password(raw_password)`` -- Sets the user's password to the given
- raw string, taking care of the password hashing. Doesn't save the
- ``User`` object.
- * ``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.)
- * ``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. ``check_password()`` for this user will
- never return ``True``. Doesn't save the ``User`` object.
- You may need this if authentication for your application takes place
- against an existing external source such as an LDAP directory.
- * ``has_usable_password()`` -- **New in Django development version.**
- Returns ``False`` if ``set_unusable_password()`` has been called for this
- user.
- * ``get_group_permissions()`` -- Returns a list of permission strings that
- the user has, through his/her groups.
- * ``get_all_permissions()`` -- Returns a list of permission strings that
- the user has, both through group and user permissions.
- * ``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``.
- * ``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``.
- * ``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``.
- * ``get_and_delete_messages()`` -- Returns a list of ``Message`` objects in
- the user's queue and deletes the messages from the queue.
- * ``email_user(subject, message, from_email=None)`` -- Sends an e-mail to
- the user. If ``from_email`` is ``None``, Django uses the
- `DEFAULT_FROM_EMAIL`_ setting.
- * ``get_profile()`` -- Returns a site-specific profile for this user.
- Raises ``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.
- .. _Django model: ../model-api/
- .. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
- .. _storing additional user information: #storing-additional-information-about-users
- Manager functions
- ~~~~~~~~~~~~~~~~~
- The ``User`` model has a custom manager that has the following helper functions:
- * ``create_user(username, email, password=None)`` -- Creates, saves and
- returns a ``User``. The ``username``, ``email`` and ``password`` are set
- as given, and the ``User`` gets ``is_active=True``.
- If no password is provided, ``set_unusable_password()`` will be called.
- See `Creating users`_ for example usage.
- * ``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
- -----------
- Creating users
- ~~~~~~~~~~~~~~
- The most basic way to create users is to use the ``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 ``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 ``password`` attribute directly unless you know what you're
- doing. This is explained in the next section.
- Passwords
- ---------
- The ``password`` attribute of a ``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 ``User.set_password()`` and ``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 ``User.check_password()``
- works correctly for a given user.
- Anonymous users
- ---------------
- ``django.contrib.auth.models.AnonymousUser`` is a class that implements
- the ``django.contrib.auth.models.User`` interface, with these differences:
- * ``id`` is always ``None``.
- * ``is_staff`` and ``is_superuser`` are always ``False``.
- * ``is_active`` is always ``False``.
- * ``groups`` and ``user_permissions`` are always empty.
- * ``is_anonymous()`` returns ``True`` instead of ``False``.
- * ``is_authenticated()`` returns ``False`` instead of ``True``.
- * ``has_perm()`` always returns ``False``.
- * ``set_password()``, ``check_password()``, ``save()``, ``delete()``,
- ``set_groups()`` and ``set_permissions()`` raise ``NotImplementedError``.
- In practice, you probably won't need to use ``AnonymousUser`` objects on your
- own, but they're used by Web requests, as explained in the next section.
- Creating superusers
- -------------------
- ``manage.py syncdb`` prompts you to create a superuser the first time you run
- it after adding ``'django.contrib.auth'`` to your ``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 ``--username`` or the ``--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 ``/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.
- 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 ``ForeignKey`` from your
- model to the ``User`` model, specified with ``unique=True`` to ensure
- only one instance of your model can be created for each ``User``.
- To indicate that this model is the user profile model for a given
- site, fill in the 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 ``manage.py 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 ``User`` object will have a method -- ``get_profile()``
- -- which returns the instance of the user profile model associated
- with that ``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 `request objects`_.
- First, install the ``SessionMiddleware`` and ``AuthenticationMiddleware``
- middlewares by adding them to your ``MIDDLEWARE_CLASSES`` setting. See the
- `session documentation`_ for more information.
- Once you have those middlewares installed, you'll be able to access
- ``request.user`` in views. ``request.user`` will give you a ``User`` object
- representing the currently logged-in user. If a user isn't currently logged in,
- ``request.user`` will be set to an instance of ``AnonymousUser`` (see the
- previous section). You can tell them apart with ``is_authenticated()``, like so::
- if request.user.is_authenticated():
- # Do something for authenticated users.
- else:
- # Do something for anonymous users.
- .. _request objects: ../request_response/#httprequest-objects
- .. _session documentation: ../sessions/
- How to log a user in
- --------------------
- Django provides two functions in ``django.contrib.auth``: ``authenticate()``
- and ``login()``.
- To authenticate a given username and password, use ``authenticate()``. It
- takes two keyword arguments, ``username`` and ``password``, and it returns
- a ``User`` object if the password is valid for the given username. If the
- password is invalid, ``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."
- To log a user in, in a view, use ``login()``. It takes an ``HttpRequest``
- object and a ``User`` object. ``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 ``authenticate()`` and ``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
- ``authenticate()`` before you call ``login()``. ``authenticate()``
- sets an attribute on the ``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
- -----------------------------------
- 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 ``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
- ---------------------
- To log out a user who has been logged in via ``django.contrib.auth.login()``,
- use ``django.contrib.auth.logout()`` within your view. It takes an
- ``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 ``logout()`` doesn't throw any errors if the user wasn't logged in.
- **New in Django development version:** When you call ``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 ``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
- ``request.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
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- As a shortcut, you can use the convenient ``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, ``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):
- # ...
- ``login_required`` does the following:
- * If the user isn't logged in, redirect to ``settings.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 ``settings.LOGIN_URL``.
- For example, using the defaults, add the following line to your URLconf::
- (r'^accounts/login/$', 'django.contrib.auth.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 ``settings.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 ``Form`` object representing the login form. See the
- `forms documentation`_ 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 ``Site``, according to the
- ``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 the
- `site framework docs`_.
- If you'd prefer not to call the template ``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 ``myapp/login.html``
- instead::
- (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
- Here's a sample ``registration/login.html`` template you can use as a starting
- point. It assumes you have a ``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:
- ``django.contrib.auth.views.logout``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- **Description:**
- 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
- ``registration/logged_out.html`` if no argument is supplied.
- **Template context:**
- * ``title``: The string "Logged out", localized.
- ``django.contrib.auth.views.logout_then_login``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- **Description:**
- 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 ``settings.LOGIN_URL`` if not supplied.
- ``django.contrib.auth.views.password_change``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- **Description:**
- 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
- ``registration/password_change_form.html`` if not supplied.
- **Template context:**
- * ``form``: The password change form.
- ``django.contrib.auth.views.password_change_done``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- **Description:**
- 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 ``registration/password_change_done.html`` if not
- supplied.
- ``django.contrib.auth.views.password_reset``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- **Description:**
- 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
- ``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
- ``registration/password_reset_email.html`` if not supplied.
- **Template context:**
- * ``form``: The form for resetting the user's password.
- ``django.contrib.auth.views.password_reset_done``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- **Description:**
- 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 ``registration/password_reset_done.html`` if not
- supplied.
- ``django.contrib.auth.views.redirect_to_login``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- **Description:**
- 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 ``settings.LOGIN_URL`` if not supplied.
- Built-in forms
- --------------
- **New in Django development version.**
- 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:
- * ``django.contrib.auth.forms.AdminPasswordChangeForm``: A form used in
- the admin interface to change a user's password.
- * ``django.contrib.auth.forms.AuthenticationForm``: A form for logging a
- user in.
- * ``django.contrib.auth.forms.PasswordChangeForm``: A form for allowing a
- user to change their password.
- * ``django.contrib.auth.forms.PasswordResetForm``: A form for resetting a
- user's password and e-mailing the new password to them.
- * ``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 ``request.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.")
- # ...
- 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 ``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):
- # ...
- ``user_passes_test`` takes a required argument: a callable that takes a
- ``User`` object and returns ``True`` if the user is allowed to view the page.
- Note that ``user_passes_test`` does not automatically check that the ``User``
- is not anonymous.
- ``user_passes_test()`` takes an optional ``login_url`` argument, which lets you
- specify the URL for your login page (``settings.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
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 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
- ``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 ``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
- ``settings.LOGIN_URL``.
- Limiting access to generic views
- --------------------------------
- To limit access to a `generic view`_, 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)
- .. _generic view: ../generic_views/
- 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 ``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 ``manage.py syncdb``;
- the first time you run ``syncdb`` after adding ``django.contrib.auth``
- to ``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 ``manage.py syncdb``.
- Custom permissions
- ------------------
- To create custom permissions for a given model object, use the ``permissions``
- `model Meta attribute`_.
- 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
- ``syncdb``.
- .. _model Meta attribute: ../model-api/#meta-options
- API reference
- -------------
- 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
- ~~~~~~
- ``Permission`` objects have the following fields:
- * ``name`` -- Required. 50 characters or fewer. Example: ``'Can vote'``.
- * ``content_type`` -- Required. A reference to the ``django_content_type``
- database table, which contains a record for each installed Django model.
- * ``codename`` -- Required. 100 characters or fewer. Example: ``'can_vote'``.
- Methods
- ~~~~~~~
- ``Permission`` objects have the standard data-access methods like any other
- `Django model`_.
- Authentication data in templates
- ================================
- The currently logged-in user and his/her permissions are made available in the
- `template context`_ when you use ``RequestContext``.
- .. admonition:: Technicality
- Technically, these variables are only made available in the template context
- if you use ``RequestContext`` *and* your ``TEMPLATE_CONTEXT_PROCESSORS``
- setting contains ``"django.core.context_processors.auth"``, which is default.
- For more, see the `RequestContext docs`_.
- .. _RequestContext docs: ../templates_python/#subclassing-context-requestcontext
- Users
- -----
- The currently logged-in user, either a ``User`` instance or an``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 ``django.core.context_processors.PermWrapper``,
- which is a template-friendly proxy of permissions.
- In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
- ``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 ``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 %}
- .. _template context: ../templates_python/
- 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 ``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:
- * To create a new message, use
- ``user_obj.message_set.create(message='message_text')``.
- * To retrieve/delete messages, use ``user_obj.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 ``RequestContext``, the currently logged-in user and his/her
- messages are made available in the `template context`_ 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 ``RequestContext`` calls ``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 `session framework`_.
- .. _session framework: ../sessions/
- 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
- ``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
- ``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, ``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 ``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
- (``get_group_permissions()``, ``get_all_permissions()``, ``has_perm()``, and
- ``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 ``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
|