|
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 Overview |
|
10 ======== |
|
11 |
|
12 The auth system consists of: |
|
13 |
|
14 * Users |
|
15 * Permissions: Binary (yes/no) flags designating whether a user may perform |
|
16 a certain task. |
|
17 * Groups: A generic way of applying labels and permissions to more than one |
|
18 user. |
|
19 * Messages: A simple way to queue messages for given users. |
|
20 |
|
21 Installation |
|
22 ============ |
|
23 |
|
24 Authentication support is bundled as a Django application in |
|
25 ``django.contrib.auth``. To install it, do the following: |
|
26 |
|
27 1. Put ``'django.contrib.auth'`` in your ``INSTALLED_APPS`` setting. |
|
28 2. Run the command ``manage.py syncdb``. |
|
29 |
|
30 Note that the default ``settings.py`` file created by |
|
31 ``django-admin.py startproject`` includes ``'django.contrib.auth'`` in |
|
32 ``INSTALLED_APPS`` for convenience. If your ``INSTALLED_APPS`` already contains |
|
33 ``'django.contrib.auth'``, feel free to run ``manage.py syncdb`` again; you |
|
34 can run that command as many times as you'd like, and each time it'll only |
|
35 install what's needed. |
|
36 |
|
37 The ``syncdb`` command creates the necessary database tables, creates |
|
38 permission objects for all installed apps that need 'em, and prompts you to |
|
39 create a superuser account the first time you run it. |
|
40 |
|
41 Once you've taken those steps, that's it. |
|
42 |
|
43 Users |
|
44 ===== |
|
45 |
|
46 Users are represented by a standard Django model, which lives in |
|
47 `django/contrib/auth/models.py`_. |
|
48 |
|
49 .. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py |
|
50 |
|
51 API reference |
|
52 ------------- |
|
53 |
|
54 Fields |
|
55 ~~~~~~ |
|
56 |
|
57 ``User`` objects have the following fields: |
|
58 |
|
59 * ``username`` -- Required. 30 characters or fewer. Alphanumeric characters |
|
60 only (letters, digits and underscores). |
|
61 * ``first_name`` -- Optional. 30 characters or fewer. |
|
62 * ``last_name`` -- Optional. 30 characters or fewer. |
|
63 * ``email`` -- Optional. E-mail address. |
|
64 * ``password`` -- Required. A hash of, and metadata about, the password. |
|
65 (Django doesn't store the raw password.) Raw passwords can be arbitrarily |
|
66 long and can contain any character. See the "Passwords" section below. |
|
67 * ``is_staff`` -- Boolean. Designates whether this user can access the |
|
68 admin site. |
|
69 * ``is_active`` -- Boolean. Designates whether this account can be used |
|
70 to log in. Set this flag to ``False`` instead of deleting accounts. |
|
71 * ``is_superuser`` -- Boolean. Designates that this user has all permissions |
|
72 without explicitly assigning them. |
|
73 * ``last_login`` -- A datetime of the user's last login. Is set to the |
|
74 current date/time by default. |
|
75 * ``date_joined`` -- A datetime designating when the account was created. |
|
76 Is set to the current date/time by default when the account is created. |
|
77 |
|
78 Methods |
|
79 ~~~~~~~ |
|
80 |
|
81 ``User`` objects have two many-to-many fields: ``groups`` and |
|
82 ``user_permissions``. ``User`` objects can access their related |
|
83 objects in the same way as any other `Django model`_:: |
|
84 |
|
85 myuser.groups = [group_list] |
|
86 myuser.groups.add(group, group,...) |
|
87 myuser.groups.remove(group, group,...) |
|
88 myuser.groups.clear() |
|
89 myuser.user_permissions = [permission_list] |
|
90 myuser.user_permissions.add(permission, permission, ...) |
|
91 myuser.user_permissions.remove(permission, permission, ...] |
|
92 myuser.user_permissions.clear() |
|
93 |
|
94 In addition to those automatic API methods, ``User`` objects have the following |
|
95 custom methods: |
|
96 |
|
97 * ``is_anonymous()`` -- Always returns ``False``. This is a way of |
|
98 differentiating ``User`` and ``AnonymousUser`` objects. Generally, you |
|
99 should prefer using ``is_authenticated()`` to this method. |
|
100 |
|
101 * ``is_authenticated()`` -- Always returns ``True``. This is a way to |
|
102 tell if the user has been authenticated. This does not imply any |
|
103 permissions, and doesn't check if the user is active - it only indicates |
|
104 that the user has provided a valid username and password. |
|
105 |
|
106 * ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``, |
|
107 with a space in between. |
|
108 |
|
109 * ``set_password(raw_password)`` -- Sets the user's password to the given |
|
110 raw string, taking care of the password hashing. Doesn't save the |
|
111 ``User`` object. |
|
112 |
|
113 * ``check_password(raw_password)`` -- Returns ``True`` if the given raw |
|
114 string is the correct password for the user. (This takes care of the |
|
115 password hashing in making the comparison.) |
|
116 |
|
117 * ``get_group_permissions()`` -- Returns a list of permission strings that |
|
118 the user has, through his/her groups. |
|
119 |
|
120 * ``get_all_permissions()`` -- Returns a list of permission strings that |
|
121 the user has, both through group and user permissions. |
|
122 |
|
123 * ``has_perm(perm)`` -- Returns ``True`` if the user has the specified |
|
124 permission, where perm is in the format ``"package.codename"``. |
|
125 If the user is inactive, this method will always return ``False``. |
|
126 |
|
127 * ``has_perms(perm_list)`` -- Returns ``True`` if the user has each of the |
|
128 specified permissions, where each perm is in the format |
|
129 ``"package.codename"``. If the user is inactive, this method will |
|
130 always return ``False``. |
|
131 |
|
132 * ``has_module_perms(package_name)`` -- Returns ``True`` if the user has |
|
133 any permissions in the given package (the Django app label). |
|
134 If the user is inactive, this method will always return ``False``. |
|
135 |
|
136 * ``get_and_delete_messages()`` -- Returns a list of ``Message`` objects in |
|
137 the user's queue and deletes the messages from the queue. |
|
138 |
|
139 * ``email_user(subject, message, from_email=None)`` -- Sends an e-mail to |
|
140 the user. If ``from_email`` is ``None``, Django uses the |
|
141 `DEFAULT_FROM_EMAIL`_ setting. |
|
142 |
|
143 * ``get_profile()`` -- Returns a site-specific profile for this user. |
|
144 Raises ``django.contrib.auth.models.SiteProfileNotAvailable`` if the current site |
|
145 doesn't allow profiles. |
|
146 |
|
147 .. _Django model: ../model_api/ |
|
148 .. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email |
|
149 |
|
150 Manager functions |
|
151 ~~~~~~~~~~~~~~~~~ |
|
152 |
|
153 The ``User`` model has a custom manager that has the following helper functions: |
|
154 |
|
155 * ``create_user(username, email, password)`` -- Creates, saves and returns |
|
156 a ``User``. The ``username``, ``email`` and ``password`` are set as |
|
157 given, and the ``User`` gets ``is_active=True``. |
|
158 |
|
159 See _`Creating users` for example usage. |
|
160 |
|
161 * ``make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')`` |
|
162 Returns a random password with the given length and given string of |
|
163 allowed characters. (Note that the default value of ``allowed_chars`` |
|
164 doesn't contain ``"I"`` or letters that look like it, to avoid user |
|
165 confusion. |
|
166 |
|
167 Basic usage |
|
168 ----------- |
|
169 |
|
170 Creating users |
|
171 ~~~~~~~~~~~~~~ |
|
172 |
|
173 The most basic way to create users is to use the ``create_user`` helper |
|
174 function that comes with Django:: |
|
175 |
|
176 >>> from django.contrib.auth.models import User |
|
177 >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword') |
|
178 |
|
179 # At this point, user is a User object ready to be saved |
|
180 # to the database. You can continue to change its attributes |
|
181 # if you want to change other fields. |
|
182 >>> user.is_staff = True |
|
183 >>> user.save() |
|
184 |
|
185 Changing passwords |
|
186 ~~~~~~~~~~~~~~~~~~ |
|
187 |
|
188 Change a password with ``set_password()``:: |
|
189 |
|
190 >>> from django.contrib.auth.models import User |
|
191 >>> u = User.objects.get(username__exact='john') |
|
192 >>> u.set_password('new password') |
|
193 >>> u.save() |
|
194 |
|
195 Don't set the ``password`` attribute directly unless you know what you're |
|
196 doing. This is explained in the next section. |
|
197 |
|
198 Passwords |
|
199 --------- |
|
200 |
|
201 The ``password`` attribute of a ``User`` object is a string in this format:: |
|
202 |
|
203 hashtype$salt$hash |
|
204 |
|
205 That's hashtype, salt and hash, separated by the dollar-sign character. |
|
206 |
|
207 Hashtype is either ``sha1`` (default) or ``md5`` -- the algorithm used to |
|
208 perform a one-way hash of the password. Salt is a random string used to salt |
|
209 the raw password to create the hash. |
|
210 |
|
211 For example:: |
|
212 |
|
213 sha1$a1976$a36cc8cbf81742a8fb52e221aaeab48ed7f58ab4 |
|
214 |
|
215 The ``User.set_password()`` and ``User.check_password()`` functions handle |
|
216 the setting and checking of these values behind the scenes. |
|
217 |
|
218 Previous Django versions, such as 0.90, used simple MD5 hashes without password |
|
219 salts. For backwards compatibility, those are still supported; they'll be |
|
220 converted automatically to the new style the first time ``check_password()`` |
|
221 works correctly for a given user. |
|
222 |
|
223 Anonymous users |
|
224 --------------- |
|
225 |
|
226 ``django.contrib.auth.models.AnonymousUser`` is a class that implements |
|
227 the ``django.contrib.auth.models.User`` interface, with these differences: |
|
228 |
|
229 * ``id`` is always ``None``. |
|
230 * ``is_anonymous()`` returns ``True`` instead of ``False``. |
|
231 * ``is_authenticated()`` returns ``False`` instead of ``True``. |
|
232 * ``has_perm()`` always returns ``False``. |
|
233 * ``set_password()``, ``check_password()``, ``save()``, ``delete()``, |
|
234 ``set_groups()`` and ``set_permissions()`` raise ``NotImplementedError``. |
|
235 |
|
236 In practice, you probably won't need to use ``AnonymousUser`` objects on your |
|
237 own, but they're used by Web requests, as explained in the next section. |
|
238 |
|
239 Creating superusers |
|
240 ------------------- |
|
241 |
|
242 ``manage.py syncdb`` prompts you to create a superuser the first time you run |
|
243 it after adding ``'django.contrib.auth'`` to your ``INSTALLED_APPS``. But if |
|
244 you need to create a superuser after that via the command line, you can use the |
|
245 ``create_superuser.py`` utility. Just run this command:: |
|
246 |
|
247 python /path/to/django/contrib/auth/create_superuser.py |
|
248 |
|
249 Make sure to substitute ``/path/to/`` with the path to the Django codebase on |
|
250 your filesystem. |
|
251 |
|
252 Authentication in Web requests |
|
253 ============================== |
|
254 |
|
255 Until now, this document has dealt with the low-level APIs for manipulating |
|
256 authentication-related objects. On a higher level, Django can hook this |
|
257 authentication framework into its system of `request objects`_. |
|
258 |
|
259 First, install the ``SessionMiddleware`` and ``AuthenticationMiddleware`` |
|
260 middlewares by adding them to your ``MIDDLEWARE_CLASSES`` setting. See the |
|
261 `session documentation`_ for more information. |
|
262 |
|
263 Once you have those middlewares installed, you'll be able to access |
|
264 ``request.user`` in views. ``request.user`` will give you a ``User`` object |
|
265 representing the currently logged-in user. If a user isn't currently logged in, |
|
266 ``request.user`` will be set to an instance of ``AnonymousUser`` (see the |
|
267 previous section). You can tell them apart with ``is_authenticated()``, like so:: |
|
268 |
|
269 if request.user.is_authenticated(): |
|
270 # Do something for authenticated users. |
|
271 else: |
|
272 # Do something for anonymous users. |
|
273 |
|
274 .. _request objects: ../request_response/#httprequest-objects |
|
275 .. _session documentation: ../sessions/ |
|
276 |
|
277 How to log a user in |
|
278 -------------------- |
|
279 |
|
280 Django provides two functions in ``django.contrib.auth``: ``authenticate()`` |
|
281 and ``login()``. |
|
282 |
|
283 To authenticate a given username and password, use ``authenticate()``. It |
|
284 takes two keyword arguments, ``username`` and ``password``, and it returns |
|
285 a ``User`` object if the password is valid for the given username. If the |
|
286 password is invalid, ``authenticate()`` returns ``None``. Example:: |
|
287 |
|
288 from django.contrib.auth import authenticate |
|
289 user = authenticate(username='john', password='secret') |
|
290 if user is not None: |
|
291 if user.is_active: |
|
292 print "You provided a correct username and password!" |
|
293 else: |
|
294 print "Your account has been disabled!" |
|
295 else: |
|
296 print "Your username and password were incorrect." |
|
297 |
|
298 To log a user in, in a view, use ``login()``. It takes an ``HttpRequest`` |
|
299 object and a ``User`` object. ``login()`` saves the user's ID in the session, |
|
300 using Django's session framework, so, as mentioned above, you'll need to make |
|
301 sure to have the session middleware installed. |
|
302 |
|
303 This example shows how you might use both ``authenticate()`` and ``login()``:: |
|
304 |
|
305 from django.contrib.auth import authenticate, login |
|
306 |
|
307 def my_view(request): |
|
308 username = request.POST['username'] |
|
309 password = request.POST['password'] |
|
310 user = authenticate(username=username, password=password) |
|
311 if user is not None: |
|
312 if user.is_active: |
|
313 login(request, user) |
|
314 # Redirect to a success page. |
|
315 else: |
|
316 # Return a 'disabled account' error message |
|
317 else: |
|
318 # Return an 'invalid login' error message. |
|
319 |
|
320 Manually checking a user's password |
|
321 ----------------------------------- |
|
322 |
|
323 If you'd like to manually authenticate a user by comparing a |
|
324 plain-text password to the hashed password in the database, use the |
|
325 convenience function `django.contrib.auth.models.check_password`. It |
|
326 takes two arguments: the plain-text password to check, and the full |
|
327 value of a user's ``password`` field in the database to check against, |
|
328 and returns ``True`` if they match, ``False`` otherwise. |
|
329 |
|
330 How to log a user out |
|
331 --------------------- |
|
332 |
|
333 To log out a user who has been logged in via ``django.contrib.auth.login()``, |
|
334 use ``django.contrib.auth.logout()`` within your view. It takes an |
|
335 ``HttpRequest`` object and has no return value. Example:: |
|
336 |
|
337 from django.contrib.auth import logout |
|
338 |
|
339 def logout_view(request): |
|
340 logout(request) |
|
341 # Redirect to a success page. |
|
342 |
|
343 Note that ``logout()`` doesn't throw any errors if the user wasn't logged in. |
|
344 |
|
345 Limiting access to logged-in users |
|
346 ---------------------------------- |
|
347 |
|
348 The raw way |
|
349 ~~~~~~~~~~~ |
|
350 |
|
351 The simple, raw way to limit access to pages is to check |
|
352 ``request.user.is_authenticated()`` and either redirect to a login page:: |
|
353 |
|
354 from django.http import HttpResponseRedirect |
|
355 |
|
356 def my_view(request): |
|
357 if not request.user.is_authenticated(): |
|
358 return HttpResponseRedirect('/login/?next=%s' % request.path) |
|
359 # ... |
|
360 |
|
361 ...or display an error message:: |
|
362 |
|
363 def my_view(request): |
|
364 if not request.user.is_authenticated(): |
|
365 return render_to_response('myapp/login_error.html') |
|
366 # ... |
|
367 |
|
368 The login_required decorator |
|
369 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
370 |
|
371 As a shortcut, you can use the convenient ``login_required`` decorator:: |
|
372 |
|
373 from django.contrib.auth.decorators import login_required |
|
374 |
|
375 def my_view(request): |
|
376 # ... |
|
377 my_view = login_required(my_view) |
|
378 |
|
379 Here's an equivalent example, using the more compact decorator syntax |
|
380 introduced in Python 2.4:: |
|
381 |
|
382 from django.contrib.auth.decorators import login_required |
|
383 |
|
384 @login_required |
|
385 def my_view(request): |
|
386 # ... |
|
387 |
|
388 ``login_required`` does the following: |
|
389 |
|
390 * If the user isn't logged in, redirect to ``/accounts/login/``, passing |
|
391 the current absolute URL in the query string as ``next``. For example: |
|
392 ``/accounts/login/?next=/polls/3/``. |
|
393 * If the user is logged in, execute the view normally. The view code is |
|
394 free to assume the user is logged in. |
|
395 |
|
396 Note that you'll need to map the appropriate Django view to ``/accounts/login/``. |
|
397 To do this, add the following line to your URLconf:: |
|
398 |
|
399 (r'^accounts/login/$', 'django.contrib.auth.views.login'), |
|
400 |
|
401 Here's what ``django.contrib.auth.views.login`` does: |
|
402 |
|
403 * If called via ``GET``, it displays a login form that POSTs to the same |
|
404 URL. More on this in a bit. |
|
405 |
|
406 * If called via ``POST``, it tries to log the user in. If login is |
|
407 successful, the view redirects to the URL specified in ``next``. If |
|
408 ``next`` isn't provided, it redirects to ``/accounts/profile/`` (which is |
|
409 currently hard-coded). If login isn't successful, it redisplays the login |
|
410 form. |
|
411 |
|
412 It's your responsibility to provide the login form in a template called |
|
413 ``registration/login.html`` by default. This template gets passed three |
|
414 template context variables: |
|
415 |
|
416 * ``form``: A ``FormWrapper`` object representing the login form. See the |
|
417 `forms documentation`_ for more on ``FormWrapper`` objects. |
|
418 * ``next``: The URL to redirect to after successful login. This may contain |
|
419 a query string, too. |
|
420 * ``site_name``: The name of the current ``Site``, according to the |
|
421 ``SITE_ID`` setting. See the `site framework docs`_. |
|
422 |
|
423 If you'd prefer not to call the template ``registration/login.html``, you can |
|
424 pass the ``template_name`` parameter via the extra arguments to the view in |
|
425 your URLconf. For example, this URLconf line would use ``myapp/login.html`` |
|
426 instead:: |
|
427 |
|
428 (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}), |
|
429 |
|
430 Here's a sample ``registration/login.html`` template you can use as a starting |
|
431 point. It assumes you have a ``base.html`` template that defines a ``content`` |
|
432 block:: |
|
433 |
|
434 {% extends "base.html" %} |
|
435 |
|
436 {% block content %} |
|
437 |
|
438 {% if form.has_errors %} |
|
439 <p>Your username and password didn't match. Please try again.</p> |
|
440 {% endif %} |
|
441 |
|
442 <form method="post" action="."> |
|
443 <table> |
|
444 <tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr> |
|
445 <tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr> |
|
446 </table> |
|
447 |
|
448 <input type="submit" value="login" /> |
|
449 <input type="hidden" name="next" value="{{ next }}" /> |
|
450 </form> |
|
451 |
|
452 {% endblock %} |
|
453 |
|
454 .. _forms documentation: ../forms/ |
|
455 .. _site framework docs: ../sites/ |
|
456 |
|
457 Other built-in views |
|
458 -------------------- |
|
459 |
|
460 In addition to the `login` view, the authentication system includes a |
|
461 few other useful built-in views: |
|
462 |
|
463 ``django.contrib.auth.views.logout`` |
|
464 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
465 |
|
466 **Description:** |
|
467 |
|
468 Logs a user out. |
|
469 |
|
470 **Optional arguments:** |
|
471 |
|
472 * ``template_name``: The full name of a template to display after |
|
473 logging the user out. This will default to |
|
474 ``registration/logged_out.html`` if no argument is supplied. |
|
475 |
|
476 **Template context:** |
|
477 |
|
478 * ``title``: The string "Logged out", localized. |
|
479 |
|
480 ``django.contrib.auth.views.logout_then_login`` |
|
481 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
482 |
|
483 **Description:** |
|
484 |
|
485 Logs a user out, then redirects to the login page. |
|
486 |
|
487 **Optional arguments:** |
|
488 |
|
489 * ``login_url``: The URL of the login page to redirect to. This |
|
490 will default to ``/accounts/login/`` if not supplied. |
|
491 |
|
492 ``django.contrib.auth.views.password_change`` |
|
493 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
494 |
|
495 **Description:** |
|
496 |
|
497 Allows a user to change their password. |
|
498 |
|
499 **Optional arguments:** |
|
500 |
|
501 * ``template_name``: The full name of a template to use for |
|
502 displaying the password change form. This will default to |
|
503 ``registration/password_change_form.html`` if not supplied. |
|
504 |
|
505 **Template context:** |
|
506 |
|
507 * ``form``: The password change form. |
|
508 |
|
509 ``django.contrib.auth.views.password_change_done`` |
|
510 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
511 |
|
512 **Description:** |
|
513 |
|
514 The page shown after a user has changed their password. |
|
515 |
|
516 **Optional arguments:** |
|
517 |
|
518 * ``template_name``: The full name of a template to use. This will |
|
519 default to ``registration/password_change_done.html`` if not |
|
520 supplied. |
|
521 |
|
522 ``django.contrib.auth.views.password_reset`` |
|
523 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
524 |
|
525 **Description:** |
|
526 |
|
527 Allows a user to reset their password, and sends them the new password |
|
528 in an email. |
|
529 |
|
530 **Optional arguments:** |
|
531 |
|
532 * ``template_name``: The full name of a template to use for |
|
533 displaying the password reset form. This will default to |
|
534 ``registration/password_reset_form.html`` if not supplied. |
|
535 |
|
536 * ``email_template_name``: The full name of a template to use for |
|
537 generating the email with the new password. This will default to |
|
538 ``registration/password_reset_email.html`` if not supplied. |
|
539 |
|
540 **Template context:** |
|
541 |
|
542 * ``form``: The form for resetting the user's password. |
|
543 |
|
544 ``django.contrib.auth.views.password_reset_done`` |
|
545 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
546 |
|
547 **Description:** |
|
548 |
|
549 The page shown after a user has reset their password. |
|
550 |
|
551 **Optional arguments:** |
|
552 |
|
553 * ``template_name``: The full name of a template to use. This will |
|
554 default to ``registration/password_reset_done.html`` if not |
|
555 supplied. |
|
556 |
|
557 ``django.contrib.auth.views.redirect_to_login`` |
|
558 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
559 |
|
560 **Description:** |
|
561 |
|
562 Redirects to the login page, and then back to another URL after a |
|
563 successful login. |
|
564 |
|
565 **Required arguments:** |
|
566 |
|
567 * ``next``: The URL to redirect to after a successful login. |
|
568 |
|
569 **Optional arguments:** |
|
570 |
|
571 * ``login_url``: The URL of the login page to redirect to. This |
|
572 will default to ``/accounts/login/`` if not supplied. |
|
573 |
|
574 Built-in manipulators |
|
575 --------------------- |
|
576 |
|
577 If you don't want to use the built-in views, but want the convenience |
|
578 of not having to write manipulators for this functionality, the |
|
579 authentication system provides several built-in manipulators: |
|
580 |
|
581 * ``django.contrib.auth.forms.AdminPasswordChangeForm``: A |
|
582 manipulator used in the admin interface to change a user's |
|
583 password. |
|
584 |
|
585 * ``django.contrib.auth.forms.AuthenticationForm``: A manipulator |
|
586 for logging a user in. |
|
587 |
|
588 * ``django.contrib.auth.forms.PasswordChangeForm``: A manipulator |
|
589 for allowing a user to change their password. |
|
590 |
|
591 * ``django.contrib.auth.forms.PasswordResetForm``: A manipulator |
|
592 for resetting a user's password and emailing the new password to |
|
593 them. |
|
594 |
|
595 * ``django.contrib.auth.forms.UserCreationForm``: A manipulator |
|
596 for creating a new user. |
|
597 |
|
598 Limiting access to logged-in users that pass a test |
|
599 --------------------------------------------------- |
|
600 |
|
601 To limit access based on certain permissions or some other test, you'd do |
|
602 essentially the same thing as described in the previous section. |
|
603 |
|
604 The simple way is to run your test on ``request.user`` in the view directly. |
|
605 For example, this view checks to make sure the user is logged in and has the |
|
606 permission ``polls.can_vote``:: |
|
607 |
|
608 def my_view(request): |
|
609 if not (request.user.is_authenticated() and request.user.has_perm('polls.can_vote')): |
|
610 return HttpResponse("You can't vote in this poll.") |
|
611 # ... |
|
612 |
|
613 As a shortcut, you can use the convenient ``user_passes_test`` decorator:: |
|
614 |
|
615 from django.contrib.auth.decorators import user_passes_test |
|
616 |
|
617 def my_view(request): |
|
618 # ... |
|
619 my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view) |
|
620 |
|
621 We're using this particular test as a relatively simple example. However, if |
|
622 you just want to test whether a permission is available to a user, you can use |
|
623 the ``permission_required()`` decorator, described later in this document. |
|
624 |
|
625 Here's the same thing, using Python 2.4's decorator syntax:: |
|
626 |
|
627 from django.contrib.auth.decorators import user_passes_test |
|
628 |
|
629 @user_passes_test(lambda u: u.has_perm('polls.can_vote')) |
|
630 def my_view(request): |
|
631 # ... |
|
632 |
|
633 ``user_passes_test`` takes a required argument: a callable that takes a |
|
634 ``User`` object and returns ``True`` if the user is allowed to view the page. |
|
635 Note that ``user_passes_test`` does not automatically check that the ``User`` |
|
636 is not anonymous. |
|
637 |
|
638 ``user_passes_test()`` takes an optional ``login_url`` argument, which lets you |
|
639 specify the URL for your login page (``/accounts/login/`` by default). |
|
640 |
|
641 Example in Python 2.3 syntax:: |
|
642 |
|
643 from django.contrib.auth.decorators import user_passes_test |
|
644 |
|
645 def my_view(request): |
|
646 # ... |
|
647 my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')(my_view) |
|
648 |
|
649 Example in Python 2.4 syntax:: |
|
650 |
|
651 from django.contrib.auth.decorators import user_passes_test |
|
652 |
|
653 @user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/') |
|
654 def my_view(request): |
|
655 # ... |
|
656 |
|
657 The permission_required decorator |
|
658 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
659 |
|
660 **New in Django development version** |
|
661 |
|
662 It's a relatively common task to check whether a user has a particular |
|
663 permission. For that reason, Django provides a shortcut for that case: the |
|
664 ``permission_required()`` decorator. Using this decorator, the earlier example |
|
665 can be written as:: |
|
666 |
|
667 from django.contrib.auth.decorators import permission_required |
|
668 |
|
669 def my_view(request): |
|
670 # ... |
|
671 my_view = permission_required('polls.can_vote')(my_view) |
|
672 |
|
673 Note that ``permission_required()`` also takes an optional ``login_url`` |
|
674 parameter. Example:: |
|
675 |
|
676 from django.contrib.auth.decorators import permission_required |
|
677 |
|
678 def my_view(request): |
|
679 # ... |
|
680 my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view) |
|
681 |
|
682 As in the ``login_required`` decorator, ``login_url`` defaults to |
|
683 ``'/accounts/login/'``. |
|
684 |
|
685 Limiting access to generic views |
|
686 -------------------------------- |
|
687 |
|
688 To limit access to a `generic view`_, write a thin wrapper around the view, |
|
689 and point your URLconf to your wrapper instead of the generic view itself. |
|
690 For example:: |
|
691 |
|
692 from django.views.generic.date_based import object_detail |
|
693 |
|
694 @login_required |
|
695 def limited_object_detail(*args, **kwargs): |
|
696 return object_detail(*args, **kwargs) |
|
697 |
|
698 .. _generic view: ../generic_views/ |
|
699 |
|
700 Permissions |
|
701 =========== |
|
702 |
|
703 Django comes with a simple permissions system. It provides a way to assign |
|
704 permissions to specific users and groups of users. |
|
705 |
|
706 It's used by the Django admin site, but you're welcome to use it in your own |
|
707 code. |
|
708 |
|
709 The Django admin site uses permissions as follows: |
|
710 |
|
711 * Access to view the "add" form and add an object is limited to users with |
|
712 the "add" permission for that type of object. |
|
713 * Access to view the change list, view the "change" form and change an |
|
714 object is limited to users with the "change" permission for that type of |
|
715 object. |
|
716 * Access to delete an object is limited to users with the "delete" |
|
717 permission for that type of object. |
|
718 |
|
719 Permissions are set globally per type of object, not per specific object |
|
720 instance. For example, it's possible to say "Mary may change news stories," but |
|
721 it's not currently possible to say "Mary may change news stories, but only the |
|
722 ones she created herself" or "Mary may only change news stories that have a |
|
723 certain status, publication date or ID." The latter functionality is something |
|
724 Django developers are currently discussing. |
|
725 |
|
726 Default permissions |
|
727 ------------------- |
|
728 |
|
729 Three basic permissions -- add, create and delete -- are automatically created |
|
730 for each Django model that has a ``class Admin`` set. Behind the scenes, these |
|
731 permissions are added to the ``auth_permission`` database table when you run |
|
732 ``manage.py syncdb``. |
|
733 |
|
734 Note that if your model doesn't have ``class Admin`` set when you run |
|
735 ``syncdb``, the permissions won't be created. If you initialize your database |
|
736 and add ``class Admin`` to models after the fact, you'll need to run |
|
737 ``manage.py syncdb`` again. It will create any missing permissions for |
|
738 all of your installed apps. |
|
739 |
|
740 Custom permissions |
|
741 ------------------ |
|
742 |
|
743 To create custom permissions for a given model object, use the ``permissions`` |
|
744 `model Meta attribute`_. |
|
745 |
|
746 This example model creates three custom permissions:: |
|
747 |
|
748 class USCitizen(models.Model): |
|
749 # ... |
|
750 class Meta: |
|
751 permissions = ( |
|
752 ("can_drive", "Can drive"), |
|
753 ("can_vote", "Can vote in elections"), |
|
754 ("can_drink", "Can drink alcohol"), |
|
755 ) |
|
756 |
|
757 The only thing this does is create those extra permissions when you run |
|
758 ``syncdb``. |
|
759 |
|
760 .. _model Meta attribute: ../model_api/#meta-options |
|
761 |
|
762 API reference |
|
763 ------------- |
|
764 |
|
765 Just like users, permissions are implemented in a Django model that lives in |
|
766 `django/contrib/auth/models.py`_. |
|
767 |
|
768 .. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py |
|
769 |
|
770 Fields |
|
771 ~~~~~~ |
|
772 |
|
773 ``Permission`` objects have the following fields: |
|
774 |
|
775 * ``name`` -- Required. 50 characters or fewer. Example: ``'Can vote'``. |
|
776 * ``content_type`` -- Required. A reference to the ``django_content_type`` |
|
777 database table, which contains a record for each installed Django model. |
|
778 * ``codename`` -- Required. 100 characters or fewer. Example: ``'can_vote'``. |
|
779 |
|
780 Methods |
|
781 ~~~~~~~ |
|
782 |
|
783 ``Permission`` objects have the standard data-access methods like any other |
|
784 `Django model`_. |
|
785 |
|
786 Authentication data in templates |
|
787 ================================ |
|
788 |
|
789 The currently logged-in user and his/her permissions are made available in the |
|
790 `template context`_ when you use ``RequestContext``. |
|
791 |
|
792 .. admonition:: Technicality |
|
793 |
|
794 Technically, these variables are only made available in the template context |
|
795 if you use ``RequestContext`` *and* your ``TEMPLATE_CONTEXT_PROCESSORS`` |
|
796 setting contains ``"django.core.context_processors.auth"``, which is default. |
|
797 For more, see the `RequestContext docs`_. |
|
798 |
|
799 .. _RequestContext docs: ../templates_python/#subclassing-context-requestcontext |
|
800 |
|
801 Users |
|
802 ----- |
|
803 |
|
804 The currently logged-in user, either a ``User`` instance or an``AnonymousUser`` |
|
805 instance, is stored in the template variable ``{{ user }}``:: |
|
806 |
|
807 {% if user.is_authenticated %} |
|
808 <p>Welcome, {{ user.username }}. Thanks for logging in.</p> |
|
809 {% else %} |
|
810 <p>Welcome, new user. Please log in.</p> |
|
811 {% endif %} |
|
812 |
|
813 Permissions |
|
814 ----------- |
|
815 |
|
816 The currently logged-in user's permissions are stored in the template variable |
|
817 ``{{ perms }}``. This is an instance of ``django.core.context_processors.PermWrapper``, |
|
818 which is a template-friendly proxy of permissions. |
|
819 |
|
820 In the ``{{ perms }}`` object, single-attribute lookup is a proxy to |
|
821 ``User.has_module_perms``. This example would display ``True`` if the logged-in |
|
822 user had any permissions in the ``foo`` app:: |
|
823 |
|
824 {{ perms.foo }} |
|
825 |
|
826 Two-level-attribute lookup is a proxy to ``User.has_perm``. This example would |
|
827 display ``True`` if the logged-in user had the permission ``foo.can_vote``:: |
|
828 |
|
829 {{ perms.foo.can_vote }} |
|
830 |
|
831 Thus, you can check permissions in template ``{% if %}`` statements:: |
|
832 |
|
833 {% if perms.foo %} |
|
834 <p>You have permission to do something in the foo app.</p> |
|
835 {% if perms.foo.can_vote %} |
|
836 <p>You can vote!</p> |
|
837 {% endif %} |
|
838 {% if perms.foo.can_drive %} |
|
839 <p>You can drive!</p> |
|
840 {% endif %} |
|
841 {% else %} |
|
842 <p>You don't have permission to do anything in the foo app.</p> |
|
843 {% endif %} |
|
844 |
|
845 .. _template context: ../templates_python/ |
|
846 |
|
847 Groups |
|
848 ====== |
|
849 |
|
850 Groups are a generic way of categorizing users so you can apply permissions, or |
|
851 some other label, to those users. A user can belong to any number of groups. |
|
852 |
|
853 A user in a group automatically has the permissions granted to that group. For |
|
854 example, if the group ``Site editors`` has the permission |
|
855 ``can_edit_home_page``, any user in that group will have that permission. |
|
856 |
|
857 Beyond permissions, groups are a convenient way to categorize users to give |
|
858 them some label, or extended functionality. For example, you could create a |
|
859 group ``'Special users'``, and you could write code that could, say, give them |
|
860 access to a members-only portion of your site, or send them members-only e-mail |
|
861 messages. |
|
862 |
|
863 Messages |
|
864 ======== |
|
865 |
|
866 The message system is a lightweight way to queue messages for given users. |
|
867 |
|
868 A message is associated with a ``User``. There's no concept of expiration or |
|
869 timestamps. |
|
870 |
|
871 Messages are used by the Django admin after successful actions. For example, |
|
872 ``"The poll Foo was created successfully."`` is a message. |
|
873 |
|
874 The API is simple: |
|
875 |
|
876 * To create a new message, use |
|
877 ``user_obj.message_set.create(message='message_text')``. |
|
878 * To retrieve/delete messages, use ``user_obj.get_and_delete_messages()``, |
|
879 which returns a list of ``Message`` objects in the user's queue (if any) |
|
880 and deletes the messages from the queue. |
|
881 |
|
882 In this example view, the system saves a message for the user after creating |
|
883 a playlist:: |
|
884 |
|
885 def create_playlist(request, songs): |
|
886 # Create the playlist with the given songs. |
|
887 # ... |
|
888 request.user.message_set.create(message="Your playlist was added successfully.") |
|
889 return render_to_response("playlists/create.html", |
|
890 context_instance=RequestContext(request)) |
|
891 |
|
892 When you use ``RequestContext``, the currently logged-in user and his/her |
|
893 messages are made available in the `template context`_ as the template variable |
|
894 ``{{ messages }}``. Here's an example of template code that displays messages:: |
|
895 |
|
896 {% if messages %} |
|
897 <ul> |
|
898 {% for message in messages %} |
|
899 <li>{{ message }}</li> |
|
900 {% endfor %} |
|
901 </ul> |
|
902 {% endif %} |
|
903 |
|
904 Note that ``RequestContext`` calls ``get_and_delete_messages`` behind the |
|
905 scenes, so any messages will be deleted even if you don't display them. |
|
906 |
|
907 Finally, note that this messages framework only works with users in the user |
|
908 database. To send messages to anonymous users, use the `session framework`_. |
|
909 |
|
910 .. _session framework: ../sessions/ |
|
911 |
|
912 Other authentication sources |
|
913 ============================ |
|
914 |
|
915 The authentication that comes with Django is good enough for most common cases, |
|
916 but you may have the need to hook into another authentication source -- that |
|
917 is, another source of usernames and passwords or authentication methods. |
|
918 |
|
919 For example, your company may already have an LDAP setup that stores a username |
|
920 and password for every employee. It'd be a hassle for both the network |
|
921 administrator and the users themselves if users had separate accounts in LDAP |
|
922 and the Django-based applications. |
|
923 |
|
924 So, to handle situations like this, the Django authentication system lets you |
|
925 plug in another authentication sources. You can override Django's default |
|
926 database-based scheme, or you can use the default system in tandem with other |
|
927 systems. |
|
928 |
|
929 Specifying authentication backends |
|
930 ---------------------------------- |
|
931 |
|
932 Behind the scenes, Django maintains a list of "authentication backends" that it |
|
933 checks for authentication. When somebody calls |
|
934 ``django.contrib.auth.authenticate()`` -- as described in "How to log a user in" |
|
935 above -- Django tries authenticating across all of its authentication backends. |
|
936 If the first authentication method fails, Django tries the second one, and so |
|
937 on, until all backends have been attempted. |
|
938 |
|
939 The list of authentication backends to use is specified in the |
|
940 ``AUTHENTICATION_BACKENDS`` setting. This should be a tuple of Python path |
|
941 names that point to Python classes that know how to authenticate. These classes |
|
942 can be anywhere on your Python path. |
|
943 |
|
944 By default, ``AUTHENTICATION_BACKENDS`` is set to:: |
|
945 |
|
946 ('django.contrib.auth.backends.ModelBackend',) |
|
947 |
|
948 That's the basic authentication scheme that checks the Django users database. |
|
949 |
|
950 The order of ``AUTHENTICATION_BACKENDS`` matters, so if the same username and |
|
951 password is valid in multiple backends, Django will stop processing at the |
|
952 first positive match. |
|
953 |
|
954 Writing an authentication backend |
|
955 --------------------------------- |
|
956 |
|
957 An authentication backend is a class that implements two methods: |
|
958 ``get_user(id)`` and ``authenticate(**credentials)``. |
|
959 |
|
960 The ``get_user`` method takes an ``id`` -- which could be a username, database |
|
961 ID or whatever -- and returns a ``User`` object. |
|
962 |
|
963 The ``authenticate`` method takes credentials as keyword arguments. Most of |
|
964 the time, it'll just look like this:: |
|
965 |
|
966 class MyBackend: |
|
967 def authenticate(self, username=None, password=None): |
|
968 # Check the username/password and return a User. |
|
969 |
|
970 But it could also authenticate a token, like so:: |
|
971 |
|
972 class MyBackend: |
|
973 def authenticate(self, token=None): |
|
974 # Check the token and return a User. |
|
975 |
|
976 Either way, ``authenticate`` should check the credentials it gets, and it |
|
977 should return a ``User`` object that matches those credentials, if the |
|
978 credentials are valid. If they're not valid, it should return ``None``. |
|
979 |
|
980 The Django admin system is tightly coupled to the Django ``User`` object |
|
981 described at the beginning of this document. For now, the best way to deal with |
|
982 this is to create a Django ``User`` object for each user that exists for your |
|
983 backend (e.g., in your LDAP directory, your external SQL database, etc.) You |
|
984 can either write a script to do this in advance, or your ``authenticate`` |
|
985 method can do it the first time a user logs in. |
|
986 |
|
987 Here's an example backend that authenticates against a username and password |
|
988 variable defined in your ``settings.py`` file and creates a Django ``User`` |
|
989 object the first time a user authenticates:: |
|
990 |
|
991 from django.conf import settings |
|
992 from django.contrib.auth.models import User, check_password |
|
993 |
|
994 class SettingsBackend: |
|
995 """ |
|
996 Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD. |
|
997 |
|
998 Use the login name, and a hash of the password. For example: |
|
999 |
|
1000 ADMIN_LOGIN = 'admin' |
|
1001 ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de' |
|
1002 """ |
|
1003 def authenticate(self, username=None, password=None): |
|
1004 login_valid = (settings.ADMIN_LOGIN == username) |
|
1005 pwd_valid = check_password(password, settings.ADMIN_PASSWORD) |
|
1006 if login_valid and pwd_valid: |
|
1007 try: |
|
1008 user = User.objects.get(username=username) |
|
1009 except User.DoesNotExist: |
|
1010 # Create a new user. Note that we can set password |
|
1011 # to anything, because it won't be checked; the password |
|
1012 # from settings.py will. |
|
1013 user = User(username=username, password='get from settings.py') |
|
1014 user.is_staff = True |
|
1015 user.is_superuser = True |
|
1016 user.save() |
|
1017 return user |
|
1018 return None |
|
1019 |
|
1020 def get_user(self, user_id): |
|
1021 try: |
|
1022 return User.objects.get(pk=user_id) |
|
1023 except User.DoesNotExist: |
|
1024 return None |