diff options
Diffstat (limited to 'parts/django/docs/topics/auth.txt')
-rw-r--r-- | parts/django/docs/topics/auth.txt | 1612 |
1 files changed, 0 insertions, 1612 deletions
diff --git a/parts/django/docs/topics/auth.txt b/parts/django/docs/topics/auth.txt deleted file mode 100644 index a58e523..0000000 --- a/parts/django/docs/topics/auth.txt +++ /dev/null @@ -1,1612 +0,0 @@ -============================= -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. - -.. deprecated:: 1.2 - The Messages component of the auth system will be removed in Django 1.4. - -Installation -============ - -Authentication support is bundled as a Django application in -``django.contrib.auth``. To install it, do the following: - - 1. Put ``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in - your :setting:`INSTALLED_APPS` setting. - (The :class:`~django.contrib.auth.models.Permission` model in - :mod:`django.contrib.auth` depends on :mod:`django.contrib.contenttypes`.) - 2. Run the command ``manage.py syncdb``. - -Note that the default :file:`settings.py` file created by -:djadmin:`django-admin.py startproject <startproject>` includes -``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in -:setting:`INSTALLED_APPS` for convenience. If your :setting:`INSTALLED_APPS` -already contains these apps, feel free to run :djadmin:`manage.py syncdb -<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). - - .. versionchanged:: 1.2 - Usernames may now contain ``@``, ``+``, ``.`` and ``-`` characters. - - .. 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 user account should be considered - active. We recommend that you set this flag to ``False`` instead of - deleting accounts; that way, if your applications have any foreign keys - to users, the foreign keys won't break. - - This doesn't necessarily control whether or not the user can log in. - Authentication backends aren't required to check for the ``is_active`` - flag, so if you want to reject a login based on ``is_active`` being - ``False``, it's up to you to check that in your own login view. - However, the :class:`~django.contrib.auth.forms.AuthenticationForm` - used by the :func:`~django.contrib.auth.views.login` view *does* - perform this check, as do the permission-checking methods such as - :meth:`~models.User.has_perm` and the authentication in the Django - admin. All of those functions/methods will return ``False`` for - inactive users. - - .. 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 :doc:`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() - - .. versionadded:: 1.0 - - 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() - - .. versionadded:: 1.0 - - Returns ``False`` if - :meth:`~django.contrib.auth.models.User.set_unusable_password()` has - been called for this user. - - .. method:: models.User.get_group_permissions(obj=None) - - Returns a set of permission strings that the user has, through his/her - groups. - - .. versionadded:: 1.2 - - If ``obj`` is passed in, only returns the group permissions for - this specific object. - - .. method:: models.User.get_all_permissions(obj=None) - - Returns a set of permission strings that the user has, both through - group and user permissions. - - .. versionadded:: 1.2 - - If ``obj`` is passed in, only returns the permissions for this - specific object. - - .. method:: models.User.has_perm(perm, obj=None) - - Returns ``True`` if the user has the specified permission, where perm is - in the format ``"<app label>.<permission codename>"``. (see - `permissions`_ section below). If the user is inactive, this method will - always return ``False``. - - .. versionadded:: 1.2 - - If ``obj`` is passed in, this method won't check for a permission for - the model, but for this specific object. - - .. method:: models.User.has_perms(perm_list, obj=None) - - Returns ``True`` if the user has each of the specified permissions, - where each perm is in the format - ``"<app label>.<permission codename>"``. If the user is inactive, - this method will always return ``False``. - - .. versionadded:: 1.2 - - If ``obj`` is passed in, this method won't check for permissions for - the model, but for the specific object. - - .. 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` and - :attr:`~django.contrib.auth.models.User.password` are set as given. The - domain portion of :attr:`~django.contrib.auth.models.User.email` is - automatically convered to lowercase, and the returned - :class:`~django.contrib.auth.models.User` object will have - :attr:`~models.User.is_active` set to ``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: - - * ``i``, ``l``, ``I``, and ``1`` (lowercase letter i, lowercase - letter L, uppercase letter i, and the number one) - * ``o``, ``O``, and ``0`` (uppercase letter o, lowercase letter o, - and zero) - -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() - -You can also create users using the Django admin site. Assuming you've enabled -the admin site and hooked it to the URL ``/admin/``, the "Add user" page is at -``/admin/auth/user/add/``. You should also see a link to "Users" in the "Auth" -section of the main admin index page. The "Add user" admin page is different -than standard admin pages in that it requires you to choose a username and -password before allowing you to edit the rest of the user's fields. - -Also note: if you want your own user account to be able to create users using -the Django admin site, you'll need to give yourself permission to add users -*and* change users (i.e., the "Add user" and "Change user" permissions). If -your account has permission to add users but not to change them, you won't be -able to add users. Why? Because if you have permission to add users, you have -the power to create superusers, which can then, in turn, change other users. So -Django requires add *and* change permissions as a slight security measure. - -Changing passwords -~~~~~~~~~~~~~~~~~~ - -.. versionadded:: 1.2 - The ``manage.py changepassword`` command was added. - -:djadmin:`manage.py changepassword *username* <changepassword>` offers a method -of changing a User's password from the command line. It prompts you to -change the password of a given user which you must enter twice. If -they both match, the new password will be changed immediately. If you -do not supply a user, the command will attempt to change the password -whose username matches the current user. - -You can also change a password programmatically, using -:meth:`~django.contrib.auth.models.User.set_password()`: - -.. code-block:: python - - >>> 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. - -.. versionadded:: 1.0 - Support for the ``crypt`` module is new in Django 1.0. - -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.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. - -.. _topics-auth-creating-superusers: - -Creating superusers -------------------- - -.. versionadded:: 1.0 - The ``manage.py createsuperuser`` command is new. - -: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:: - - 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.OneToOneField` from your model to the -:class:`~django.contrib.auth.models.User` model. This will 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 name of the application (case sensitive) in which the user - profile model is defined (in other words, the - name which was passed to :djadmin:`manage.py startapp <startapp>` to create - the application). - -2. The name of the model (not case sensitive) 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`. - -The method :class:`~django.contrib.auth.models.User.get_profile()` -does not create the profile, if it does not exist. You need to -register a handler for the signal -:attr:`django.db.models.signals.post_save` on the User model, and, in -the handler, if created=True, create the associated user profile. - -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 :doc:`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: - -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. - - .. versionchanged:: 1.0 - Calling ``logout()`` now cleans session data. - - 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([redirect_field_name=REDIRECT_FIELD_NAME]) - - As a shortcut, you can use the convenient - :func:`~django.contrib.auth.decorators.login_required` decorator:: - - from django.contrib.auth.decorators import login_required - - @login_required - 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>`, passing the current absolute - path in the query string. 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. - - By default, the path that the user should be redirected to upon - successful authentication is stored in a query string parameter called - ``"next"``. If you would prefer to use a different name for this parameter, - :func:`~django.contrib.auth.decorators.login_required` takes an - optional ``redirect_field_name`` parameter:: - - from django.contrib.auth.decorators import login_required - - @login_required(redirect_field_name='my_redirect_field') - def my_view(request): - ... - - If you provide a value to ``redirect_field_name``, you will most - likely need to customize your login template as well, since the template - context variable which stores the redirect path will use the value of - ``redirect_field_name`` as it's key rather than ``"next"`` (the default). - - 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(request, [template_name, redirect_field_name, authentication_form]) - - 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 four - template context variables: - - * ``form``: A :class:`~django.forms.Form` object representing the login - form. See the :doc:`forms documentation </topics/forms/index>` for - more on ``Form`` objects. - - * ``next``: The URL to redirect to after successful login. This may - contain a query string, too. - - * ``site``: The current :class:`~django.contrib.sites.models.Site`, - according to the :setting:`SITE_ID` setting. If you don't have the - site framework installed, this will be set to an instance of - :class:`~django.contrib.sites.models.RequestSite`, which derives the - site name and domain from the current - :class:`~django.http.HttpRequest`. - - * ``site_name``: An alias for ``site.name``. If you don't have the site - framework installed, this will be set to the value of - :attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`. - For more on sites, see :doc:`/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'}), - - You can also specify the name of the ``GET`` field which contains the URL - to redirect to after login by passing ``redirect_field_name`` to the view. - By default, the field is called ``next``. - - 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: - - .. code-block:: html+django - - {% 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="{% url django.contrib.auth.views.login %}"> - {% csrf_token %} - <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 %} - - .. versionadded:: 1.2 - - If you are using alternate authentication (see - :ref:`authentication-backends`) you can pass a custom authentication form - to the login view via the ``authentication_form`` parameter. This form must - accept a ``request`` keyword argument in its ``__init__`` method, and - provide a ``get_user`` method which returns the authenticated user object - (this method is only ever called after successful form validation). - - .. _forms documentation: ../forms/ - .. _site framework docs: ../sites/ - -Other built-in views --------------------- - -In addition to the :func:`~views.login` view, the authentication system -includes a few other useful built-in views located in -:mod:`django.contrib.auth.views`: - -.. function:: views.logout(request, [next_page, template_name, redirect_field_name]) - - Logs a user out. - - **Optional arguments:** - - * ``next_page``: The URL to redirect to after logout. - - * ``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. - - * ``redirect_field_name``: The name of a ``GET`` field containing the - URL to redirect to after log out. Overrides ``next_page`` if the given - ``GET`` parameter is passed. - - **Template context:** - - * ``title``: The string "Logged out", localized. - -.. function:: views.logout_then_login(request[, login_url]) - - 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:: views.password_change(request[, template_name, post_change_redirect, password_change_form]) - - 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. - - * ``post_change_redirect``: The URL to redirect to after a successful - password change. - - * .. versionadded:: 1.2 - - ``password_change_form``: A custom "change password" form which must - accept a ``user`` keyword argument. The form is responsible for - actually changing the user's password. - - - **Template context:** - - * ``form``: The password change form. - -.. function:: views.password_change_done(request[, template_name]) - - 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:: views.password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect]) - - Allows a user to reset their password by generating a one-time use link - that can be used to reset the password, and sending that link to the - user's registered e-mail address. - - **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. - - * ``password_reset_form``: Form that will be used to set the password. - Defaults to :class:`~django.contrib.auth.forms.PasswordResetForm`. - - * ``token_generator``: Instance of the class to check the password. This - will default to ``default_token_generator``, it's an instance of - ``django.contrib.auth.tokens.PasswordResetTokenGenerator``. - - * ``post_reset_redirect``: The URL to redirect to after a successful - password change. - - **Template context:** - - * ``form``: The form for resetting the user's password. - -.. function:: views.password_reset_done(request[, template_name]) - - 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:: views.redirect_to_login(next[, login_url, redirect_field_name]) - - 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. - - * ``redirect_field_name``: The name of a ``GET`` field containing the - URL to redirect to after log out. Overrides ``next`` if the given - ``GET`` parameter is passed. - -.. function:: password_reset_confirm(request[, uidb36, token, template_name, token_generator, set_password_form, post_reset_redirect]) - - Presents a form for entering a new password. - - **Optional arguments:** - - * ``uidb36``: The user's id encoded in base 36. This will default to - ``None``. - * ``token``: Token to check that the password is valid. This will default to ``None``. - * ``template_name``: The full name of a template to display the confirm - password view. Default value is :file:`registration/password_reset_confirm.html`. - * ``token_generator``: Instance of the class to check the password. This - will default to ``default_token_generator``, it's an instance of - ``django.contrib.auth.tokens.PasswordResetTokenGenerator``. - * ``set_password_form``: Form that will be used to set the password. - This will default to ``SetPasswordForm``. - * ``post_reset_redirect``: URL to redirect after the password reset - done. This will default to ``None``. - -.. function:: password_reset_complete(request[,template_name]) - - Presents a view which informs the user that the password has been - successfully changed. - - **Optional arguments:** - - * ``template_name``: The full name of a template to display the view. - This will default to :file:`registration/password_reset_complete.html`. - -Built-in forms --------------- - -.. module:: django.contrib.auth.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 located in :mod:`django.contrib.auth.forms`: - -.. class:: AdminPasswordChangeForm - - A form used in the admin interface to change a user's password. - -.. class:: AuthenticationForm - - A form for logging a user in. - -.. class:: PasswordChangeForm - - A form for allowing a user to change their password. - -.. class:: PasswordResetForm - - A form for generating and e-mailing a one-time use link to reset a - user's password. - -.. class:: SetPasswordForm - - A form that lets a user change his/her password without entering the old - password. - -.. class:: UserChangeForm - - A form used in the admin interface to change a user's information and - permissions. - -.. class:: UserCreationForm - - A form for creating a new user. - -Limiting access to logged-in users that pass a test ---------------------------------------------------- - -.. currentmodule:: django.contrib.auth - -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.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 - - @user_passes_test(lambda u: u.has_perm('polls.can_vote')) - def my_view(request): - ... - - 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. - - :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). - - For example:: - - 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 - - @permission_required('polls.can_vote') - def my_view(request): - ... - - As for the :meth:`User.has_perm` method, permission names take the form - ``"<app label>.<permission codename>"`` (i.e. ``polls.can_vote`` for a - permission on a model in the ``polls`` application). - - 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 - - @permission_required('polls.can_vote', login_url='/loginpage/') - def my_view(request): - ... - - As in the :func:`~decorators.login_required` decorator, ``login_url`` - defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>`. - -Limiting access to generic views --------------------------------- - -To limit access to a :doc:`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: - -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>`. - -Assuming you have an application with an -:attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``, -to test for basic permissions you should use: - - * add: ``user.has_perm('foo.add_bar')`` - * change: ``user.has_perm('foo.change_bar')`` - * delete: ``user.has_perm('foo.delete_bar')`` - -.. _custom-permissions: - -Custom permissions ------------------- - -To create custom permissions for a given model object, use the ``permissions`` -:ref:`model Meta attribute <meta-options>`. - -This example Task model creates three custom permissions, i.e., actions users -can or cannot do with Task instances, specific to your appication:: - - class Task(models.Model): - ... - class Meta: - permissions = ( - ("can_view", "Can see available tasks"), - ("can_change_status", "Can change the status of tasks"), - ("can_close", "Can remove a task by setting its status as closed"), - ) - -The only thing this does is create those extra permissions when you run -:djadmin:`manage.py syncdb <syncdb>`. Your code is in charge of checking the -value of these permissions when an user is trying to access the functionality -provided by the application (viewing tasks, changing the status of tasks, -closing tasks.) - -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 :doc:`Django model </ref/models/instances>`. - -Authentication data in templates -================================ - -The currently logged-in user and his/her permissions are made available in the -:doc:`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.contrib.auth.context_processors.auth"``, which is default. For - more, see the :ref:`RequestContext docs <subclassing-context-requestcontext>`. - -Users ------ - -When rendering a template :class:`~django.template.context.RequestContext`, 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 }}``: - -.. code-block:: html+django - - {% if user.is_authenticated %} - <p>Welcome, {{ user.username }}. Thanks for logging in.</p> - {% else %} - <p>Welcome, new user. Please log in.</p> - {% endif %} - -This template context variable is not available if a ``RequestContext`` is not -being used. - -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: - -.. code-block:: html+django - - {% 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 -======== - -.. deprecated:: 1.2 - This functionality will be removed in Django 1.4. You should use the - :doc:`messages framework </ref/contrib/messages>` for all new projects and - begin to update your existing code immediately. - -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 -:doc:`template context </ref/templates/api>` as the template variable -``{{ messages }}``. Here's an example of template code that displays messages: - -.. code-block:: html+django - - {% if messages %} - <ul> - {% for message in messages %} - <li>{{ message }}</li> - {% endfor %} - </ul> - {% endif %} - -.. versionchanged:: 1.2 - The ``messages`` template variable uses a backwards compatible method in the - :doc:`messages framework </ref/contrib/messages>` to retrieve messages from - both the user ``Message`` model and from the new framework. Unlike in - previous revisions, the messages will not be erased unless they are actually - displayed. - -Finally, note that this messages framework only works with users in the user -database. To send messages to anonymous users, use the -:doc:`messages framework </ref/contrib/messages>`. - -.. _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 other authentication sources. You can override Django's default -database-based scheme, or you can use the default system in tandem with other -systems. - -See the :doc:`authentication backend reference </ref/authbackends>` -for information on the authentication backends included with Django. - -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 :ref:`How to log -a user 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. - -.. note:: - - Once a user has authenticated, Django stores which backend was used to - authenticate the user in the user's session, and re-uses the same backend - for subsequent authentication attempts for that user. This effectively means - that authentication sources are cached, so if you change - :setting:`AUTHENTICATION_BACKENDS`, you'll need to clear out session data if - you need to force users to re-authenticate using different methods. A simple - way to do that is simply to execute ``Session.objects.all().delete()``. - -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 - -Authorization for anonymous users -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. versionchanged:: 1.2 - -An anonymous user is one that is not authenticated i.e. they have provided no -valid authentication details. However, that does not necessarily mean they are -not authorized to do anything. At the most basic level, most Web sites -authorize anonymous users to browse most of the site, and many allow anonymous -posting of comments etc. - -Django's permission framework does not have a place to store permissions for -anonymous users. However, it has a foundation that allows custom authentication -backends to specify authorization for anonymous users. This is especially useful -for the authors of re-usable apps, who can delegate all questions of authorization -to the auth backend, rather than needing settings, for example, to control -anonymous access. - -To enable this in your own backend, you must set the class attribute -``supports_anonymous_user`` to ``True``. (This precaution is to maintain -compatibility with backends that assume that all user objects are actual -instances of the :class:`django.contrib.auth.models.User` class). With this -in place, :class:`django.contrib.auth.models.AnonymousUser` will delegate all -the relevant permission methods to the authentication backends. - -A nonexistent ``supports_anonymous_user`` attribute will raise a hidden -``PendingDeprecationWarning`` if used in Django 1.2. In Django 1.3, this -warning will be upgraded to a ``DeprecationWarning``, which will be displayed -loudly. Additionally ``supports_anonymous_user`` will be set to ``False``. -Django 1.4 will assume that every backend supports anonymous users being -passed to the authorization methods. - -Handling object permissions ---------------------------- - -Django's permission framework has a foundation for object permissions, though -there is no implementation for it in the core. That means that checking for -object permissions will always return ``False`` or an empty list (depending on -the check performed). - -To enable object permissions in your own -:doc:`authentication backend </ref/authbackends>` you'll just have -to allow passing an ``obj`` parameter to the permission methods and set the -``supports_object_permissions`` class attribute to ``True``. - -A nonexistent ``supports_object_permissions`` will raise a hidden -``PendingDeprecationWarning`` if used in Django 1.2. In Django 1.3, this -warning will be upgraded to a ``DeprecationWarning``, which will be displayed -loudly. Additionally ``supports_object_permissions`` will be set to ``False``. -Django 1.4 will assume that every backend supports object permissions and -won't check for the existence of ``supports_object_permissions``, which -means not supporting ``obj`` as a parameter will raise a ``TypeError``. |