Django

Code

root/django/branches/0.90-bugfixes/docs/authentication.txt

Revision 1221, 17.8 kB (checked in by adrian, 3 years ago)

Fixed #783 -- Added AnonymousUser?.id = None. Thanks, EABinGA

Line 
1 =============================
2 User authentication in Django
3 =============================
4
5 Django comes with a user authentication system. It handles user accounts,
6 groups, permissions and cookie-based user sessions. This document explains how
7 things work.
8
9 The basics
10 ==========
11
12 Django supports authentication out of the box. The ``django-admin.py init``
13 command, used to initialize a database with Django's core database tables,
14 creates the infrastructure for the auth system. You don't have to do anything
15 else to use authentication.
16
17 The auth system consists of:
18
19     * Users
20     * Permissions: Binary (yes/no) flags designating whether a user may perform
21       a certain task.
22     * Groups: A generic way of applying labels and permissions to more than one
23       user.
24     * Messages: A simple way to queue messages for given users.
25
26 Users
27 =====
28
29 Users are represented by a standard Django model, which lives in
30 `django/models/auth.py`_.
31
32 .. _django/models/auth.py: http://code.djangoproject.com/browser/django/trunk/django/models/auth.py
33
34 API reference
35 -------------
36
37 Fields
38 ~~~~~~
39
40 ``User`` objects have the following fields:
41
42     * ``username`` -- Required. 30 characters or fewer. Alphanumeric characters
43       only (letters, digits and underscores).
44     * ``first_name`` -- Optional. 30 characters or fewer.
45     * ``last_name`` -- Optional. 30 characters or fewer.
46     * ``email`` -- Optional. E-mail address.
47     * ``password_md5`` -- Required. An MD5 hash of the password. (Django
48       doesn't store the raw password.) Raw passwords can be arbitrarily long
49       and can contain any character.
50     * ``is_staff`` -- Boolean. Designates whether this user can access the
51       admin site.
52     * ``is_active`` -- Boolean. Designates whether this user account is valid.
53       Set this to ``False`` instead of deleting accounts.
54     * ``is_superuser`` -- Boolean. Designates whether this user has permission
55       to do anything (according to the permission system).
56     * ``last_login`` -- A datetime of the user's last login. Is set to the
57       current date/time by default.
58     * ``date_joined`` -- A datetime designating when the account was created.
59       Is set to the current date/time by default when the account is created.
60
61 Methods
62 ~~~~~~~
63
64 ``User`` objects have two many-to-many fields: ``groups`` and
65 ``user_permissions``. Because of those relationships, ``User`` objects get
66 data-access methods like any other `Django model`_:
67
68     * ``get_group_list(**kwargs)``
69     * ``set_groups(id_list)``
70     * ``get_permission_list(**kwargs)``
71     * ``set_user_permissions(id_list)``
72
73 In addition to those automatic API methods, ``User`` objects have the following
74 methods:
75
76     * ``is_anonymous()`` -- Always returns ``False``. This is a way of
77       comparing ``User`` objects to anonymous users.
78
79     * ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``,
80       with a space in between.
81
82     * ``set_password(raw_password)`` -- Sets the user's password to the given
83       raw string, taking care of the MD5 hashing. Doesn't save the ``User``
84       object.
85
86     * ``check_password(raw_password)`` -- Returns ``True`` if the given raw
87       string is the correct password for the user.
88
89     * ``get_group_permissions()`` -- Returns a list of permission strings that
90       the user has, through his/her groups.
91
92     * ``get_all_permissions()`` -- Returns a list of permission strings that
93       the user has, both through group and user permissions.
94
95     * ``has_perm(perm)`` -- Returns ``True`` if the user has the specified
96       permission.
97
98     * ``has_perms(perm_list)`` -- Returns ``True`` if the user has each of the
99       specified permissions.
100
101     * ``has_module_perms(package_name)`` -- Returns ``True`` if the user has
102       any permissions in the given package (the Django app label).
103
104     * ``get_and_delete_messages()`` -- Returns a list of ``Message`` objects in
105       the user's queue and deletes the messages from the queue.
106
107     * ``email_user(subject, message, from_email=None)`` -- Sends an e-mail to
108       the user. If ``from_email`` is ``None``, Django uses the
109       `DEFAULT_FROM_EMAIL`_ setting.
110
111     * ``get_profile()`` -- Returns a site-specific profile for this user.
112       Raises ``django.models.auth.SiteProfileNotAvailable`` if the current site
113       doesn't allow profiles.
114
115 .. _Django model: http://www.djangoproject.com/documentation/model_api/
116 .. _DEFAULT_FROM_EMAIL: http://www.djangoproject.com/documentation/settings/#default-from-email
117
118 Module functions
119 ~~~~~~~~~~~~~~~~
120
121 The ``django.models.auth.users`` module has the following helper functions:
122
123     * ``create_user(username, email, password)`` -- Creates, saves and returns
124       a ``User``. The ``username``, ``email`` and ``password`` are set as
125       given, and the ``User`` gets ``is_active=True``.
126
127     * ``make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')``
128       -- Returns a random password with the given length and given string of
129       allowed characters. (Note that the default value of ``allowed_chars``
130       doesn't contain ``"I"`` or letters that look like it, to avoid user
131       confusion.
132
133 Basic usage
134 -----------
135
136 Creating users
137 ~~~~~~~~~~~~~~
138
139 The most basic way to create users is to use the standard Django
140 `database API`_. Just create and save a ``User`` object::
141
142     >>> from django.models.auth import users
143     >>> import md5
144     >>> p = md5.new('johnpassword').hexdigest()
145     >>> u = users.User(username='john', first_name='John', last_name='lennon',
146     ...     email='lennon@thebeatles.com', password_md5=p, is_staff=True,
147     ...     is_active=True, is_superuser=False)
148     >>> u.save()
149
150 Note that ``password_md5`` requires the raw MD5 hash (as created by
151 ``md5.new().hexdigest()``). Because that's a pain, there's a ``create_user``
152 helper function::
153
154     >>> from django.models.auth import users
155     >>> u = users.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
156
157 .. _database API: http://www.djangoproject.com/documentation/db_api/
158
159 Changing passwords
160 ~~~~~~~~~~~~~~~~~~
161
162 Change a password with ``set_password()``::
163
164     >>> from django.models.auth import users
165     >>> u = users.get_object(username__exact='john')
166     >>> u.set_password('new password')
167     >>> u.save()
168
169 Anonymous users
170 ---------------
171
172 ``django.parts.auth.anonymoususers.AnonymousUser`` is a class that implements
173 the ``django.models.auth.users.User`` interface, with these differences:
174
175     * ``id`` is always ``None``.
176     * ``is_anonymous()`` returns ``True`` instead of ``False``.
177     * ``has_perm()`` always returns ``False``.
178     * ``set_password()``, ``check_password()``, ``set_groups()`` and
179       ``set_permissions()`` raise ``NotImplementedError``.
180
181 In practice, you probably won't need to use ``AnonymousUser`` objects on your
182 own, but they're used by Web requests, as explained in the next section.
183
184 Authentication in Web requests
185 ==============================
186
187 Until now, this document has dealt with the low-level APIs for manipulating
188 authentication-related objects. On a higher level, Django hooks this
189 authentication framework into its system of `request objects`_.
190
191 In any Django view, ``request.user`` will give you a ``User`` object
192 representing the currently logged-in user. If a user isn't currently logged in,
193 ``request.user`` will be set to an instance of ``AnonymousUser`` (see the
194 previous section). You can tell them apart with ``is_anonymous()``, like so::
195
196     if request.user.is_anonymous():
197         # Do something for anonymous users.
198     else:
199         # Do something for logged-in users.
200
201 If you want to use ``request.user`` in your view code, make sure you have
202 ``SessionMiddleware`` enabled. See the `session documentation`_ for more
203 information.
204
205 .. _request objects: http://www.djangoproject.com/documentation/request_response/#httprequest-objects
206 .. _session documentation: http://www.djangoproject.com/documentation/sessions/
207
208 Limiting access to logged-in users
209 ----------------------------------
210
211 The raw way
212 ~~~~~~~~~~~
213
214 The simple, raw way to limit access to pages is to check
215 ``request.user.is_anonymous()`` and either redirect to a login page::
216
217     from django.utils.httpwrappers import HttpResponseRedirect
218
219     def my_view(request):
220         if request.user.is_anonymous():
221             return HttpResponseRedirect('/login/?next=%s' % request.path)
222         # ...
223
224 ...or display an error message::
225
226     def my_view(request):
227         if request.user.is_anonymous():
228             return render_to_response('myapp/login_error')
229         # ...
230
231 The login_required decorator
232 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
233
234 As a shortcut, you can use the convenient ``login_required`` decorator::
235
236     from django.views.decorators.auth import login_required
237
238     def my_view(request):
239         # ...
240     my_view = login_required(my_view)
241
242 Here's the same thing, using Python 2.4's decorator syntax::
243
244     from django.views.decorators.auth import login_required
245
246     @login_required
247     def my_view(request):
248         # ...
249
250 ``login_required`` does the following:
251
252     * If the user isn't logged in, redirect to ``/accounts/login/``, passing
253       the current absolute URL in the query string as ``next``. For example:
254       ``/accounts/login/?next=/polls/3/``.
255     * If the user is logged in, execute the view normally. The view code is
256       free to assume the user is logged in.
257
258 Limiting access to logged-in users that pass a test
259 ---------------------------------------------------
260
261 To limit access based on certain permissions or some other test, you'd do
262 essentially the same thing as described in the previous section.
263
264 The simple way is to run your test on ``request.user`` in the view directly.
265 For example, this view checks to make sure the user is logged in and has the
266 permission ``polls.can_vote``::
267
268     def my_view(request):
269         if request.user.is_anonymous() or not request.user.has_perm('polls.can_vote'):
270             return HttpResponse("You can't vote in this poll.")
271         # ...
272
273 As a shortcut, you can use the convenient ``user_passes_test`` decorator::
274
275     from django.views.decorators.auth import user_passes_test
276
277     @user_passes_test(lambda u: u.has_perm('polls.can_vote'))
278     def my_view(request):
279         # ...
280
281 ``user_passes_test`` takes a required argument: a callable that takes a
282 ``User`` object and returns ``True`` if the user is allowed to view the page.
283 Note that ``user_passes_test`` does not automatically check that the ``User``
284 is not anonymous.
285
286 Limiting access to generic views
287 --------------------------------
288
289 To limit access to a `generic view`_, write a thin wrapper around the view,
290 and point your URLconf to your wrapper instead of the generic view itself.
291 For example::
292
293     from django.views.generic.date_based import object_detail
294
295     @login_required
296     def limited_object_detail(*args, **kwargs):
297         return object_detail(*args, **kwargs)
298
299 .. _generic view: http://www.djangoproject.com/documentation/generic_views/
300
301 Permissions
302 ===========
303
304 Django comes with a simple permissions system. It provides a way to assign
305 permissions to specific users and groups of users.
306
307 It's used by the Django admin site, but you're welcome to use it in your own
308 code.
309
310 The Django admin site uses permissions as follows:
311
312     * Access to view the "add" form and add an object is limited to users with
313       the "add" permission for that type of object.
314     * Access to view the change list, view the "change" form and change an
315       object is limited to users with the "change" permission for that type of
316       object.
317     * Access to delete an object is limited to users with the "delete"
318       permission for that type of object.
319
320 Permissions are set globally per type of object, not per specific object
321 instance. For example, it's possible to say "Mary may change news stories," but
322 it's not currently possible to say "Mary may change news stories, but only the
323 ones she created herself" or "Mary may only change news stories that have a
324 certain status or publication date." The latter functionality is something
325 Django developers are currently discussing.
326
327 Default permissions
328 -------------------
329
330 Three basic permissions -- add, create and delete -- are automatically created
331 for each Django model that has ``admin`` set. Behind the scenes, these
332 permissions are added to the ``auth_permissions`` database table when you run
333 ``django-admin.py install [app]``. You can view the exact SQL ``INSERT``
334 statements by running ``django-admin.py sqlinitialdata [app]``.
335
336 Note that if your model doesn't have ``admin`` set when you run
337 ``django-admin.py install``, the permissions won't be created. If you
338 initialize your database and add ``admin`` to models after the fact, you'll
339 need to add the permissions to the database manually. Do this by running
340 ``django-admin.py installperms [app]``, which creates any missing permissions
341 for the given app.
342
343 Custom permissions
344 ------------------
345
346 To create custom permissions for a given model object, use the ``permissions``
347 `model META attribute`_.
348
349 This example model creates three custom permissions::
350
351     class USCitizen(meta.Model):
352         # ...
353         class META:
354             permissions = (
355                 ("can_drive", "Can drive"),
356                 ("can_vote", "Can vote in elections"),
357                 ("can_drink", "Can drink alcohol"),
358             )
359
360 .. _model META attribute: http://www.djangoproject.com/documentation/model_api/#meta-options
361
362 API reference
363 -------------
364
365 Just like users, permissions are implemented in a Django model that lives in
366 `django/models/auth.py`_.
367
368 Fields
369 ~~~~~~
370
371 ``Permission`` objects have the following fields:
372
373     * ``name`` -- Required. 50 characters or fewer. Example: ``'Can vote'``.
374     * ``package`` -- Required. A reference to the ``packages`` database table,
375       which contains a record for each installed Django application.
376     * ``codename`` -- Required. 100 characters or fewer. Example: ``'can_vote'``.
377
378 Methods
379 ~~~~~~~
380
381 ``Permission`` objects have the standard data-access methods like any other
382 `Django model`_:
383
384 Authentication data in templates
385 ================================
386
387 The currently logged-in user and his/her permissions are made available in the
388 `template context`_ when you use ``DjangoContext``.
389
390 Users
391 -----
392
393 The currently logged-in user, either a ``User`` object or an``AnonymousUser``
394 instance, is stored in the template variable ``{{ user }}``::
395
396     {% if user.is_anonymous %}
397         <p>Welcome, new user. Please log in.</p>
398     {% else %}
399         <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
400     {% endif %}
401
402 Permissions
403 -----------
404
405 The currently logged-in user's permissions are stored in the template variable
406 ``{{ perms }}``. This is an instance of ``django.core.extensions.PermWrapper``,
407 which is a template-friendly proxy of permissions.
408
409 In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
410 ``User.has_module_perms``. This example would display ``True`` if the logged-in
411 user had any permissions in the ``foo`` app::
412
413     {{ perms.foo }}
414
415 Two-level-attribute lookup is a proxy to ``User.has_perm``. This example would
416 display ``True`` if the logged-in user had the permission ``foo.can_vote``::
417
418     {{ perms.foo.can_vote }}
419
420 Thus, you can check permissions in template ``{% if %}`` statements::
421
422     {% if perms.foo %}
423         <p>You have permission to do something in the foo app.</p>
424         {% if perms.foo.can_vote %}
425             <p>You can vote!</p>
426         {% endif %}
427         {% if perms.foo.can_drive %}
428             <p>You can drive!</p>
429         {% endif %}
430     {% else %}
431         <p>You don't have permission to do anything in the foo app.</p>
432     {% endif %}
433
434 .. _template context: http://www.djangoproject.com/documentation/templates_python/
435
436 Groups
437 ======
438
439 Groups are a generic way of categorizing users to apply permissions, or some
440 other label, to those users. A user can belong to any number of groups.
441
442 A user in a group automatically has the permissions granted to that group. For
443 example, if the group ``Site editors`` has the permission
444 ``can_edit_home_page``, any user in that group will have that permission.
445
446 Beyond permissions, groups are a convenient way to categorize users to apply
447 some label, or extended functionality, to them. For example, you could create
448 a group ``'Special users'``, and you could write code that would do special
449 things to those users -- such as giving them access to a members-only portion
450 of your site, or sending them members-only e-mail messages.
451
452 Messages
453 ========
454
455 The message system is a lightweight way to queue messages for given users.
456
457 A message is associated with a User. There's no concept of expiration or
458 timestamps.
459
460 Messages are used by the Django admin after successful actions. For example,
461 ``"The poll Foo was created successfully."`` is a message.
462
463 The API is simple::
464
465     * To add messages, use ``user.add_message(message_text)``.
466     * To retrieve/delete messages, use ``user.get_and_delete_messages()``,
467       which returns a list of ``Message`` objects in the user's queue (if any)
468       and deletes the messages from the queue.
469
470 In this example view, the system saves a message for the user after creating
471 a playlist::
472
473     def create_playlist(request, songs):
474         # Create the playlist with the given songs.
475         # ...
476         request.user.add_message("Your playlist was added successfully.")
477         return render_to_response("playlists/create", context_instance=DjangoContext(request))
478
479 When you use ``DjangoContext``, the currently logged-in user and his/her
480 messages are made available in the `template context`_ as the template variable
481 ``{{ messages }}``. Here's an example of template code that displays messages::
482
483     {% if messages %}
484     <ul>
485         {% for message in messages %}
486         <li>{{ message.message }}</li>
487         {% endfor %}
488     </ul>
489     {% endif %}
490
491 Note that ``DjangoContext`` calls ``get_and_delete_messages`` behind the
492 scenes, so any messages will be deleted even if you don't display them.
493
494 Finally, note that this messages framework only works with users in the user
495 database. To send messages to anonymous users, use the `session framework`_.
496
497 .. _session framework: http://www.djangoproject.com/documentation/sessions/
Note: See TracBrowser for help on using the browser.