12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696 |
- =============================
- 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.
- 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. Usernames may contain alphanumeric,
- ``_``, ``@``, ``+``, ``.`` 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. Email 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, and the default backends do not. 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 or a custom authentication backend. However, the
- :class:`~django.contrib.auth.forms.AuthenticationForm` used by the
- :func:`~django.contrib.auth.views.login` view (which is the default)
- *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: ``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.get_username()
- Returns the username for the user. Since the User model can be swapped
- out, you should use this method instead of referencing the username
- attribute directly.
- .. 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()
- 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()
- 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.
- 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.
- 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``.
- 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``.
- 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.email_user(subject, message, from_email=None)
- Sends an email 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()
- .. deprecated:: 1.5
- With the introduction of :ref:`custom User models <auth-custom-user>`,
- the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
- model is no longer supported. See the
- :doc:`Django 1.5 release notes</releases/1.5>` for more information.
- Returns a site-specific profile for this user. Raises
- :exc:`django.contrib.auth.models.SiteProfileNotAvailable` if the
- current site doesn't allow profiles, or
- :exc:`django.core.exceptions.ObjectDoesNotExist` if the user does not
- have a profile. 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=None, password=None)
- .. versionchanged:: 1.4
- The ``email`` parameter was made optional. The username
- parameter is now checked for emptiness and raises a
- :exc:`~exceptions.ValueError` in case of a negative result.
- 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 converted 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
- ~~~~~~~~~~~~~~~~~~
- :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.
- .. _auth_password_storage:
- How Django stores passwords
- ---------------------------
- .. versionadded:: 1.4
- Django 1.4 introduces a new flexible password storage system and uses
- PBKDF2 by default. Previous versions of Django used SHA1, and other
- algorithms couldn't be chosen.
- The :attr:`~django.contrib.auth.models.User.password` attribute of a
- :class:`~django.contrib.auth.models.User` object is a string in this format::
- algorithm$hash
- That's a storage algorithm, and hash, separated by the dollar-sign
- character. The algorithm is one of a number of one way hashing or password
- storage algorithms Django can use; see below. The hash is the result of the one-
- way function.
- By default, Django uses the PBKDF2_ algorithm with a SHA256 hash, a
- password stretching mechanism recommended by NIST_. This should be
- sufficient for most users: it's quite secure, requiring massive
- amounts of computing time to break.
- However, depending on your requirements, you may choose a different
- algorithm, or even use a custom algorithm to match your specific
- security situation. Again, most users shouldn't need to do this -- if
- you're not sure, you probably don't. If you do, please read on:
- Django chooses the an algorithm by consulting the :setting:`PASSWORD_HASHERS`
- setting. This is a list of hashing algorithm classes that this Django
- installation supports. The first entry in this list (that is,
- ``settings.PASSWORD_HASHERS[0]``) will be used to store passwords, and all the
- other entries are valid hashers that can be used to check existing passwords.
- This means that if you want to use a different algorithm, you'll need to modify
- :setting:`PASSWORD_HASHERS` to list your preferred algorithm first in the list.
- The default for :setting:`PASSWORD_HASHERS` is::
- PASSWORD_HASHERS = (
- 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
- 'django.contrib.auth.hashers.BCryptPasswordHasher',
- 'django.contrib.auth.hashers.SHA1PasswordHasher',
- 'django.contrib.auth.hashers.MD5PasswordHasher',
- 'django.contrib.auth.hashers.CryptPasswordHasher',
- )
- This means that Django will use PBKDF2_ to store all passwords, but will support
- checking passwords stored with PBKDF2SHA1, bcrypt_, SHA1_, etc. The next few
- sections describe a couple of common ways advanced users may want to modify this
- setting.
- .. _bcrypt_usage:
- Using bcrypt with Django
- ~~~~~~~~~~~~~~~~~~~~~~~~
- Bcrypt_ is a popular password storage algorithm that's specifically designed
- for long-term password storage. It's not the default used by Django since it
- requires the use of third-party libraries, but since many people may want to
- use it Django supports bcrypt with minimal effort.
- To use Bcrypt as your default storage algorithm, do the following:
- 1. Install the `py-bcrypt`_ library (probably by running ``sudo pip install
- py-bcrypt``, or downloading the library and installing it with ``python
- setup.py install``).
- 2. Modify :setting:`PASSWORD_HASHERS` to list ``BCryptPasswordHasher``
- first. That is, in your settings file, you'd put::
- PASSWORD_HASHERS = (
- 'django.contrib.auth.hashers.BCryptPasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
- 'django.contrib.auth.hashers.SHA1PasswordHasher',
- 'django.contrib.auth.hashers.MD5PasswordHasher',
- 'django.contrib.auth.hashers.CryptPasswordHasher',
- )
- (You need to keep the other entries in this list, or else Django won't
- be able to upgrade passwords; see below).
- That's it -- now your Django install will use Bcrypt as the default storage
- algorithm.
- .. admonition:: Other bcrypt implementations
- There are several other implementations that allow bcrypt to be
- used with Django. Django's bcrypt support is NOT directly
- compatible with these. To upgrade, you will need to modify the
- hashes in your database to be in the form `bcrypt$(raw bcrypt
- output)`. For example:
- `bcrypt$$2a$12$NT0I31Sa7ihGEWpka9ASYrEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy`.
- Increasing the work factor
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- The PBKDF2 and bcrypt algorithms use a number of iterations or rounds of
- hashing. This deliberately slows down attackers, making attacks against hashed
- passwords harder. However, as computing power increases, the number of
- iterations needs to be increased. We've chosen a reasonable default (and will
- increase it with each release of Django), but you may wish to tune it up or
- down, depending on your security needs and available processing power. To do so,
- you'll subclass the appropriate algorithm and override the ``iterations``
- parameters. For example, to increase the number of iterations used by the
- default PBKDF2 algorithm:
- 1. Create a subclass of ``django.contrib.auth.hashers.PBKDF2PasswordHasher``::
- from django.contrib.auth.hashers import PBKDF2PasswordHasher
- class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
- """
- A subclass of PBKDF2PasswordHasher that uses 100 times more iterations.
- """
- iterations = PBKDF2PasswordHasher.iterations * 100
- Save this somewhere in your project. For example, you might put this in
- a file like ``myproject/hashers.py``.
- 2. Add your new hasher as the first entry in :setting:`PASSWORD_HASHERS`::
- PASSWORD_HASHERS = (
- 'myproject.hashers.MyPBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
- 'django.contrib.auth.hashers.BCryptPasswordHasher',
- 'django.contrib.auth.hashers.SHA1PasswordHasher',
- 'django.contrib.auth.hashers.MD5PasswordHasher',
- 'django.contrib.auth.hashers.CryptPasswordHasher',
- )
- That's it -- now your Django install will use more iterations when it
- stores passwords using PBKDF2.
- Password upgrading
- ~~~~~~~~~~~~~~~~~~
- When users log in, if their passwords are stored with anything other than
- the preferred algorithm, Django will automatically upgrade the algorithm
- to the preferred one. This means that old installs of Django will get
- automatically more secure as users log in, and it also means that you
- can switch to new (and better) storage algorithms as they get invented.
- However, Django can only upgrade passwords that use algorithms mentioned in
- :setting:`PASSWORD_HASHERS`, so as you upgrade to new systems you should make
- sure never to *remove* entries from this list. If you do, users using un-
- mentioned algorithms won't be able to upgrade.
- .. _sha1: http://en.wikipedia.org/wiki/SHA1
- .. _pbkdf2: http://en.wikipedia.org/wiki/PBKDF2
- .. _nist: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
- .. _bcrypt: http://en.wikipedia.org/wiki/Bcrypt
- .. _py-bcrypt: http://pypi.python.org/pypi/py-bcrypt/
- 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:`~exceptions.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
- -------------------
- :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
- ------------------------------------------
- .. deprecated:: 1.5
- With the introduction of :ref:`custom User models <auth-custom-user>`,
- the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
- model is no longer supported. See the
- :doc:`Django 1.5 release notes</releases/1.5>` for more information.
- 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` named ``user`` 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`. For example::
- from django.contrib.auth.models import User
- class UserProfile(models.Model):
- # This field is required.
- user = models.OneToOneField(User)
- # Other fields here
- accepted_eula = models.BooleanField()
- favorite_animal = models.CharField(max_length=20, default="Dragons.")
- 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 a profile if one does not exist. You need to register a handler
- for the User model's :attr:`django.db.models.signals.post_save` signal and, in
- the handler, if ``created`` is ``True``, create the associated user profile::
- # in models.py
- from django.contrib.auth.models import User
- from django.db.models.signals import post_save
- # definition of UserProfile from above
- # ...
- def create_user_profile(sender, instance, created, **kwargs):
- if created:
- UserProfile.objects.create(user=instance)
- post_save.connect(create_user_profile, sender=User)
- .. seealso:: :doc:`/topics/signals` for more information on Django's signal
- dispatcher.
- Adding UserProfile fields to the admin
- --------------------------------------
- To add the UserProfile fields to the user page in the admin, define an
- :class:`~django.contrib.admin.InlineModelAdmin` (for this example, we'll use a
- :class:`~django.contrib.admin.StackedInline`) in your app's ``admin.py`` and
- add it to a ``UserAdmin`` class which is registered with the
- :class:`~django.contrib.auth.models.User` class::
- from django.contrib import admin
- from django.contrib.auth.admin import UserAdmin
- from django.contrib.auth.models import User
- from my_user_profile_app.models import UserProfile
- # Define an inline admin descriptor for UserProfile model
- # which acts a bit like a singleton
- class UserProfileInline(admin.StackedInline):
- model = UserProfile
- can_delete = False
- verbose_name_plural = 'profile'
- # Define a new User admin
- class UserAdmin(UserAdmin):
- inlines = (UserProfileInline, )
- # Re-register UserAdmin
- admin.site.unregister(User)
- admin.site.register(User, UserAdmin)
- 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.
- Note that data set during the anonymous session is retained when the user
- logs in.
- 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 managing a user's password
- -----------------------------------
- .. currentmodule:: django.contrib.auth.hashers
- .. versionadded:: 1.4
- The :mod:`django.contrib.auth.hashers` module provides a set of functions
- to create and validate hashed password. You can use them independently
- from the ``User`` model.
- .. function:: check_password(password, encoded)
- .. versionadded:: 1.4
- 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.hashers.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.
- .. function:: make_password(password[, salt, hashers])
- .. versionadded:: 1.4
- Creates a hashed password in the format used by this application. It takes
- one mandatory argument: the password in plain-text. Optionally, you can
- provide a salt and a hashing algorithm to use, if you don't want to use the
- defaults (first entry of ``PASSWORD_HASHERS`` setting).
- Currently supported algorithms are: ``'pbkdf2_sha256'``, ``'pbkdf2_sha1'``,
- ``'bcrypt'`` (see :ref:`bcrypt_usage`), ``'sha1'``, ``'md5'``,
- ``'unsalted_md5'`` (only for backward compatibility) and ``'crypt'``
- if you have the ``crypt`` library installed. If the password argument is
- ``None``, an unusable password is returned (a one that will be never
- accepted by :func:`django.contrib.auth.hashers.check_password`).
- .. function:: is_password_usable(encoded_password)
- .. versionadded:: 1.4
- Checks if the given string is a hashed password that has a chance
- of being verified against :func:`django.contrib.auth.hashers.check_password`.
- How to log a user out
- ---------------------
- .. currentmodule:: django.contrib.auth
- .. 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.
- 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()`.
- .. _topics-auth-signals:
- Login and logout signals
- ------------------------
- The auth framework uses two :doc:`signals </topics/signals>` that can be used
- for notification when a user logs in or out.
- .. data:: django.contrib.auth.signals.user_logged_in
- :module:
- Sent when a user logs in successfully.
- Arguments sent with this signal:
- ``sender``
- The class of the user that just logged in.
- ``request``
- The current :class:`~django.http.HttpRequest` instance.
- ``user``
- The user instance that just logged in.
- .. data:: django.contrib.auth.signals.user_logged_out
- :module:
- Sent when the logout method is called.
- ``sender``
- As above: the class of the user that just logged out or ``None``
- if the user was not authenticated.
- ``request``
- The current :class:`~django.http.HttpRequest` instance.
- ``user``
- The user instance that just logged out or ``None`` if the
- user was not authenticated.
- .. data:: django.contrib.auth.signals.user_login_failed
- :module:
- .. versionadded:: 1.5
- Sent when the user failed to login successfully
- ``sender``
- The name of the module used for authentication.
- ``credentials``
- A dictonary of keyword arguments containing the user credentials that were
- passed to :func:`~django.contrib.auth.authenticate()` or your own custom
- authentication backend. Credentials matching a set of 'sensitive' patterns,
- (including password) will not be sent in the clear as part of the signal.
- 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, login_url=None])
- 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):
- ...
- Note that 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 its key rather than ``"next"`` (the default).
- :func:`~django.contrib.auth.decorators.login_required` also takes an
- optional ``login_url`` parameter. Example::
- from django.contrib.auth.decorators import login_required
- @login_required(login_url='/accounts/login/')
- def my_view(request):
- ...
- Note that if you don't specify the ``login_url`` parameter, 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'),
- .. versionchanged:: 1.5
- As of version 1.5 :setting:`settings.LOGIN_URL <LOGIN_URL>` now also accepts
- view function names and :ref:`named URL patterns <naming-url-patterns>`.
- This allows you to freely remap your login view within your URLconf
- without having to update the setting.
- .. function:: views.login(request, [template_name, redirect_field_name, authentication_form])
- **URL name:** ``login``
- See :doc:`the URL documentation </topics/http/urls>` for details on using
- named URL patterns.
- 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 %}
- 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/
- .. versionadded:: 1.4
- The :func:`~views.login` view and the :ref:`other-built-in-views` now all
- return a :class:`~django.template.response.TemplateResponse` instance,
- which allows you to easily customize the response data before rendering.
- For more details, see the
- :doc:`TemplateResponse documentation </ref/template-response>`.
- .. _other-built-in-views:
- Other built-in views
- --------------------
- .. module:: django.contrib.auth.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:: logout(request, [next_page, template_name, redirect_field_name])
- Logs a user out.
- **URL name:** ``logout``
- See :doc:`the URL documentation </topics/http/urls>` for details on using
- named URL patterns.
- **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. Defaults 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.
- * ``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`.
- .. function:: logout_then_login(request[, login_url])
- Logs a user out, then redirects to the login page.
- **URL name:** No default URL provided
- **Optional arguments:**
- * ``login_url``: The URL of the login page to redirect to.
- Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
- .. function:: password_change(request[, template_name, post_change_redirect, password_change_form])
- Allows a user to change their password.
- **URL name:** ``password_change``
- **Optional arguments:**
- * ``template_name``: The full name of a template to use for
- displaying the password change form. Defaults to
- :file:`registration/password_change_form.html` if not supplied.
- * ``post_change_redirect``: The URL to redirect to after a successful
- password change.
- * ``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. Defaults to
- :class:`~django.contrib.auth.forms.PasswordChangeForm`.
- **Template context:**
- * ``form``: The password change form (see ``password_change_form`` above).
- .. function:: password_change_done(request[, template_name])
- The page shown after a user has changed their password.
- **URL name:** ``password_change_done``
- **Optional arguments:**
- * ``template_name``: The full name of a template to use.
- Defaults to :file:`registration/password_change_done.html` if not
- supplied.
- .. function:: password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email])
- 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 email address.
- .. versionchanged:: 1.4
- Users flagged with an unusable password (see
- :meth:`~django.contrib.auth.models.User.set_unusable_password()`
- will not be able to request a password reset to prevent misuse
- when using an external authentication source like LDAP.
- **URL name:** ``password_reset``
- **Optional arguments:**
- * ``template_name``: The full name of a template to use for
- displaying the password reset form. Defaults to
- :file:`registration/password_reset_form.html` if not supplied.
- * ``email_template_name``: The full name of a template to use for
- generating the email with the reset password link. Defaults to
- :file:`registration/password_reset_email.html` if not supplied.
- * ``subject_template_name``: The full name of a template to use for
- the subject of the email with the reset password link. Defaults
- to :file:`registration/password_reset_subject.txt` if not supplied.
- .. versionadded:: 1.4
- * ``password_reset_form``: Form that will be used to get the email of
- the user to reset the password for. Defaults to
- :class:`~django.contrib.auth.forms.PasswordResetForm`.
- * ``token_generator``: Instance of the class to check the one time link.
- 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 reset request.
- * ``from_email``: A valid email address. By default Django uses
- the :setting:`DEFAULT_FROM_EMAIL`.
- **Template context:**
- * ``form``: The form (see ``password_reset_form`` above) for resetting
- the user's password.
- **Email template context:**
- * ``email``: An alias for ``user.email``
- * ``user``: The current :class:`~django.contrib.auth.models.User`,
- according to the ``email`` form field. Only active users are able to
- reset their passwords (``User.is_active is True``).
- * ``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`.
- * ``domain``: An alias for ``site.domain``. If you don't have the site
- framework installed, this will be set to the value of
- ``request.get_host()``.
- * ``protocol``: http or https
- * ``uid``: The user's id encoded in base 36.
- * ``token``: Token to check that the reset link is valid.
- Sample ``registration/password_reset_email.html`` (email body template):
- .. code-block:: html+django
- Someone asked for password reset for email {{ email }}. Follow the link below:
- {{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid token=token %}
- The same template context is used for subject template. Subject must be
- single line plain text string.
- .. function:: password_reset_done(request[, template_name])
- The page shown after a user has been emailed a link to reset their
- password. This view is called by default if the :func:`password_reset` view
- doesn't have an explicit ``post_reset_redirect`` URL set.
- **URL name:** ``password_reset_done``
- **Optional arguments:**
- * ``template_name``: The full name of a template to use.
- Defaults to :file:`registration/password_reset_done.html` if not
- supplied.
- .. 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.
- **URL name:** ``password_reset_confirm``
- **Optional arguments:**
- * ``uidb36``: The user's id encoded in base 36. Defaults to ``None``.
- * ``token``: Token to check that the password is valid. Defaults 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.
- Defaults to :class:`~django.contrib.auth.forms.SetPasswordForm`
- * ``post_reset_redirect``: URL to redirect after the password reset
- done. Defaults to ``None``.
- **Template context:**
- * ``form``: The form (see ``set_password_form`` above) for setting the
- new user's password.
- * ``validlink``: Boolean, True if the link (combination of uidb36 and
- token) is valid or unused yet.
- .. function:: password_reset_complete(request[,template_name])
- Presents a view which informs the user that the password has been
- successfully changed.
- **URL name:** ``password_reset_complete``
- **Optional arguments:**
- * ``template_name``: The full name of a template to display the view.
- Defaults to :file:`registration/password_reset_complete.html`.
- Helper functions
- ----------------
- .. currentmodule:: django.contrib.auth.views
- .. function:: 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.
- Defaults 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.
- .. _built-in-auth-forms:
- 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 emailing 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.decorators
- 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:: user_passes_test(func, [login_url=None])
- 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:: permission_required([login_url=None, raise_exception=False])
- 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>`.
- .. versionchanged:: 1.4
- Added ``raise_exception`` parameter. If given, the decorator will raise
- :exc:`~django.core.exceptions.PermissionDenied`, prompting
- :ref:`the 403 (HTTP Forbidden) view<http_forbidden_view>` instead of
- redirecting to the login page.
- .. currentmodule:: django.contrib.auth
- Applying permissions to generic views
- -------------------------------------
- To apply a permission to a :doc:`class-based generic view
- </ref/class-based-views/index>`, decorate the :meth:`View.dispatch
- <django.views.generic.base.View.dispatch>` method on the class. See
- :ref:`decorating-class-based-views` for details.
- .. _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 can be set not only per type of object, but also per specific
- object instance. By using the
- :meth:`~django.contrib.admin.ModelAdmin.has_add_permission`,
- :meth:`~django.contrib.admin.ModelAdmin.has_change_permission` and
- :meth:`~django.contrib.admin.ModelAdmin.has_delete_permission` methods provided
- by the :class:`~django.contrib.admin.ModelAdmin` class, it is possible to
- customize permissions for different object instances of the same type.
- 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 application::
- class Task(models.Model):
- ...
- class Meta:
- permissions = (
- ("view_task", "Can see available tasks"),
- ("change_task_status", "Can change the status of tasks"),
- ("close_task", "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.) Continuing the above example, the following checks if a user may
- view tasks::
- user.has_perm('app.view_task')
- API reference
- -------------
- .. currentmodule:: django.contrib.auth.models
- .. class:: models.Permission
- Fields
- ~~~~~~
- :class:`~django.contrib.auth.models.Permission` objects have the following
- fields:
- .. attribute:: Permission.name
- Required. 50 characters or fewer. Example: ``'Can vote'``.
- .. attribute:: Permission.content_type
- Required. A reference to the ``django_content_type`` database table, which
- contains a record for each installed Django model.
- .. attribute:: 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>`.
- .. currentmodule:: django.contrib.auth
- Programmatically creating permissions
- -------------------------------------
- While custom permissions can be defined within a model's ``Meta`` class, you
- can also create permissions directly. For example, you can create the
- ``can_publish`` permission for a ``BlogPost`` model in ``myapp``::
- from django.contrib.auth.models import Group, Permission
- from django.contrib.contenttypes.models import ContentType
- content_type = ContentType.objects.get(app_label='myapp', model='BlogPost')
- permission = Permission.objects.create(codename='can_publish',
- name='Can Publish Posts',
- content_type=content_type)
- The permission can then be assigned to a
- :class:`~django.contrib.auth.models.User` via its ``user_permissions``
- attribute or to a :class:`~django.contrib.auth.models.Group` via its
- ``permissions`` attribute.
- 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.contrib.auth.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 %}
- .. versionadded:: 1.5
- Permission lookup by "if in".
- It is possible to also look permissions up by ``{% if in %}`` statements.
- For example:
- .. code-block:: html+django
- {% if 'foo' in perms %}
- {% if 'foo.can_vote' in perms %}
- <p>In lookup works, too.</p>
- {% endif %}
- {% 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 email
- messages.
- API reference
- -------------
- .. class:: models.Group
- Fields
- ~~~~~~
- :class:`~django.contrib.auth.models.Group` objects have the following fields:
- .. attribute:: Group.name
- Required. 80 characters or fewer. Any characters are permitted. Example:
- ``'Awesome Users'``.
- .. attribute:: Group.permissions
- Many-to-many field to :class:`~django.contrib.auth.models.Permissions`::
- group.permissions = [permission_list]
- group.permissions.add(permission, permission, ...)
- group.permissions.remove(permission, permission, ...)
- group.permissions.clear()
- .. _auth-custom-user:
- Customizing the User model
- ==========================
- .. versionadded:: 1.5
- Some kinds of projects may have authentication requirements for which Django's
- built-in :class:`~django.contrib.auth.models.User` model is not always
- appropriate. For instance, on some sites it makes more sense to use an email
- address as your identification token instead of a username.
- Django allows you to override the default User model by providing a value for
- the :setting:`AUTH_USER_MODEL` setting that references a custom model::
- AUTH_USER_MODEL = 'myapp.MyUser'
- This dotted pair describes the name of the Django app, and the name of the Django
- model that you wish to use as your User model.
- .. admonition:: Warning
- Changing :setting:`AUTH_USER_MODEL` has a big effect on your database
- structure. It changes the tables that are available, and it will affect the
- construction of foreign keys and many-to-many relationships. If you intend
- to set :setting:`AUTH_USER_MODEL`, you should set it before running
- ``manage.py syncdb`` for the first time.
- If you have an existing project and you want to migrate to using a custom
- User model, you may need to look into using a migration tool like South_
- to ease the transition.
- .. _South: http://south.aeracode.org
- Referencing the User model
- --------------------------
- If you reference :class:`~django.contrib.auth.models.User` directly (for
- example, by referring to it in a foreign key), your code will not work in
- projects where the :setting:`AUTH_USER_MODEL` setting has been changed to a
- different User model.
- Instead of referring to :class:`~django.contrib.auth.models.User` directly,
- you should reference the user model using
- :func:`django.contrib.auth.get_user_model()`. This method will return the
- currently active User model -- the custom User model if one is specified, or
- :class:`~django.contrib.auth.User` otherwise.
- When you define a foreign key or many-to-many relations to the User model,
- you should specify the custom model using the :setting:`AUTH_USER_MODEL`
- setting. For example::
- from django.conf import settings
- from django.db import models
- class Article(models.Model)
- author = models.ForeignKey(settings.AUTH_USER_MODEL)
- Specifying a custom User model
- ------------------------------
- .. admonition:: Model design considerations
- Think carefully before handling information not directly related to
- authentication in your custom User Model.
- It may be better to store app-specific user information in a model
- that has a relation with the User model. That allows each app to specify
- its own user data requirements without risking conflicts with other
- apps. On the other hand, queries to retrieve this related information
- will involve a database join, which may have an effect on performance.
- Django expects your custom User model to meet some minimum requirements.
- 1. Your model must have a single unique field that can be used for
- identification purposes. This can be a username, an email address,
- or any other unique attribute.
- 2. Your model must provide a way to address the user in a "short" and
- "long" form. The most common interpretation of this would be to use
- the user's given name as the "short" identifier, and the user's full
- name as the "long" identifier. However, there are no constraints on
- what these two methods return - if you want, they can return exactly
- the same value.
- The easiest way to construct a compliant custom User model is to inherit from
- :class:`~django.contrib.auth.models.AbstractBaseUser`.
- :class:`~django.contrib.auth.models.AbstractBaseUser` provides the core
- implementation of a `User` model, including hashed passwords and tokenized
- password resets. You must then provide some key implementation details:
- .. class:: models.CustomUser
- .. attribute:: User.USERNAME_FIELD
- A string describing the name of the field on the User model that is
- used as the unique identifier. This will usually be a username of
- some kind, but it can also be an email address, or any other unique
- identifier. In the following example, the field `identifier` is used
- as the identifying field::
- class MyUser(AbstractBaseUser):
- identifier = models.CharField(max_length=40, unique=True, db_index=True)
- ...
- USERNAME_FIELD = 'identifier'
- .. attribute:: User.REQUIRED_FIELDS
- A list of the field names that *must* be provided when creating
- a user. For example, here is the partial definition for a User model
- that defines two required fields - a date of birth and height::
- class MyUser(AbstractBaseUser):
- ...
- date_of_birth = models.DateField()
- height = models.FloatField()
- ...
- REQUIRED_FIELDS = ['date_of_birth', 'height']
- .. note::
- ``REQUIRED_FIELDS`` must contain all required fields on your User
- model, but should *not* contain the ``USERNAME_FIELD``.
- .. attribute:: User.is_active
- A boolean attribute that indicates whether the user is considered
- "active". This attribute is provided as an attribute on
- ``AbstractBaseUser`` defaulting to ``True``. How you choose to
- implement it will depend on the details of your chosen auth backends.
- See the documentation of the :attr:`attribute on the builtin user model
- <django.contrib.auth.models.User.is_active>` for details.
- .. method:: User.get_full_name():
- A longer formal identifier for the user. A common interpretation
- would be the full name name of the user, but it can be any string that
- identifies the user.
- .. method:: User.get_short_name():
- A short, informal identifier for the user. A common interpretation
- would be the first name of the user, but it can be any string that
- identifies the user in an informal way. It may also return the same
- value as :meth:`django.contrib.auth.User.get_full_name()`.
- The following methods are available on any subclass of
- :class:`~django.contrib.auth.models.AbstractBaseUser`:
- .. class:: models.AbstractBaseUser
- .. method:: models.AbstractBaseUser.get_username()
- Returns the value of the field nominated by ``USERNAME_FIELD``.
- .. method:: models.AbstractBaseUser.is_anonymous()
- Always returns ``False``. This is a way of differentiating
- from :class:`~django.contrib.auth.models.AnonymousUser` objects.
- Generally, you should prefer using
- :meth:`~django.contrib.auth.models.AbstractBaseUser.is_authenticated()` to this
- method.
- .. method:: models.AbstractBaseUser.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.AbstractBaseUser.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.AbstractBaseUser` object.
- .. method:: models.AbstractBaseUser.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.AbstractBaseUser.set_unusable_password()
- 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.AbstractBaseUser.check_password()` for this user
- will never return ``True``. Doesn't save the
- :class:`~django.contrib.auth.models.AbstractBaseUser` object.
- You may need this if authentication for your application takes place
- against an existing external source such as an LDAP directory.
- .. method:: models.AbstractBaseUser.has_usable_password()
- Returns ``False`` if
- :meth:`~django.contrib.auth.models.AbstractBaseUser.set_unusable_password()` has
- been called for this user.
- You should also define a custom manager for your User model. If your User
- model defines `username` and `email` fields the same as Django's default User,
- you can just install Django's
- :class:`~django.contrib.auth.models.UserManager`; however, if your User model
- defines different fields, you will need to define a custom manager that
- extends :class:`~django.contrib.auth.models.BaseUserManager` providing two
- additional methods:
- .. class:: models.CustomUserManager
- .. method:: models.CustomUserManager.create_user(*username_field*, password=None, **other_fields)
- The prototype of `create_user()` should accept the username field,
- plus all required fields as arguments. For example, if your user model
- uses `email` as the username field, and has `date_of_birth` as a required
- fields, then create_user should be defined as::
- def create_user(self, email, date_of_birth, password=None):
- # create user here
- .. method:: models.CustomUserManager.create_superuser(*username_field*, password, **other_fields)
- The prototype of `create_superuser()` should accept the username field,
- plus all required fields as arguments. For example, if your user model
- uses `email` as the username field, and has `date_of_birth` as a required
- fields, then create_superuser should be defined as::
- def create_superuser(self, email, date_of_birth, password):
- # create superuser here
- Unlike `create_user()`, `create_superuser()` *must* require the caller
- to provider a password.
- :class:`~django.contrib.auth.models.BaseUserManager` provides the following
- utility methods:
- .. class:: models.BaseUserManager
- .. method:: models.BaseUserManager.normalize_email(email)
- A classmethod that normalizes email addresses by lowercasing
- the domain portion of the email address.
- .. method:: models.BaseUserManager.get_by_natural_key(username)
- Retrieves a user instance using the contents of the field
- nominated by ``USERNAME_FIELD``.
- .. method:: models.BaseUserManager.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)
- Extending Django's default User
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you're entirely happy with Django's :class:`~django.contrib.auth.models.User`
- model and you just want to add some additional profile information, you can
- simply subclass :class:`~django.contrib.auth.models.AbstractUser` and add your
- custom profile fields.
- Custom users and the built-in auth forms
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- As you may expect, built-in Django's :ref:`forms <built-in-auth-forms>`
- and :ref:`views <other-built-in-views>` make certain assumptions about
- the user model that they are working with.
- If your user model doesn't follow the same assumptions, it may be necessary to define
- a replacement form, and pass that form in as part of the configuration of the
- auth views.
- * :class:`~django.contrib.auth.forms.UserCreationForm`
- Depends on the :class:`~django.contrib.auth.models.User` model.
- Must be re-written for any custom user model.
- * :class:`~django.contrib.auth.forms.UserChangeForm`
- Depends on the :class:`~django.contrib.auth.models.User` model.
- Must be re-written for any custom user model.
- * :class:`~django.contrib.auth.forms.AuthenticationForm`
- Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`,
- and will adapt to use the field defined in `USERNAME_FIELD`.
- * :class:`~django.contrib.auth.forms.PasswordResetForm`
- Assumes that the user model has an integer primary key, has a field named
- `email` that can be used to identify the user, and a boolean field
- named `is_active` to prevent password resets for inactive users.
- * :class:`~django.contrib.auth.forms.SetPasswordForm`
- Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
- * :class:`~django.contrib.auth.forms.PasswordChangeForm`
- Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
- * :class:`~django.contrib.auth.forms.AdminPasswordChangeForm`
- Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
- Custom users and django.contrib.admin
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you want your custom User model to also work with Admin, your User model must
- define some additional attributes and methods. These methods allow the admin to
- control access of the User to admin content:
- .. attribute:: User.is_staff
- Returns True if the user is allowed to have access to the admin site.
- .. attribute:: User.is_active
- Returns True if the user account is currently active.
- .. method:: User.has_perm(perm, obj=None):
- Returns True if the user has the named permission. If `obj` is
- provided, the permission needs to be checked against a specific object
- instance.
- .. method:: User.has_module_perms(app_label):
- Returns True if the user has permission to access models in
- the given app.
- You will also need to register your custom User model with the admin. If
- your custom User model extends :class:`~django.contrib.auth.models.AbstractUser`,
- you can use Django's existing :class:`~django.contrib.auth.admin.UserAdmin`
- class. However, if your User model extends
- :class:`~django.contrib.auth.models.AbstractBaseUser`, you'll need to define
- a custom ModelAdmin class. It may be possible to subclass the default
- :class:`~django.contrib.auth.admin.UserAdmin`; however, you'll need to
- override any of the definitions that refer to fields on
- :class:`~django.contrib.auth.models.AbstractUser` that aren't on your
- custom User class.
- Custom users and permissions
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- To make it easy to include Django's permission framework into your own User
- class, Django provides :class:`~django.contrib.auth.model.PermissionsMixin`.
- This is an abstract model you can include in the class heirarchy for your User
- model, giving you all the methods and database fields necessary to support
- Django's permission model.
- :class:`~django.contrib.auth.model.PermissionsMixin` provides the following
- methods and attributes:
- .. class:: models.PermissionsMixin
- .. attribute:: models.PermissionsMixin.is_superuser
- Boolean. Designates that this user has all permissions without
- explicitly assigning them.
- .. method:: models.PermissionsMixin.get_group_permissions(obj=None)
- Returns a set of permission strings that the user has, through his/her
- groups.
- If ``obj`` is passed in, only returns the group permissions for
- this specific object.
- .. method:: models.PermissionsMixin.get_all_permissions(obj=None)
- Returns a set of permission strings that the user has, both through
- group and user permissions.
- If ``obj`` is passed in, only returns the permissions for this
- specific object.
- .. method:: models.PermissionsMixin.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`_). If the user is inactive, this method will
- always return ``False``.
- If ``obj`` is passed in, this method won't check for a permission for
- the model, but for this specific object.
- .. method:: models.PermissionsMixin.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``.
- If ``obj`` is passed in, this method won't check for permissions for
- the model, but for the specific object.
- .. method:: models.PermissionsMixin.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``.
- .. admonition:: ModelBackend
- If you don't include the
- :class:`~django.contrib.auth.model.PermissionsMixin`, you must ensure you
- don't invoke the permissions methods on ``ModelBackend``. ``ModelBackend``
- assumes that certain fields are available on your user model. If your User
- model doesn't provide those fields, you will receive database errors when
- you check permissions.
- Custom users and Proxy models
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- One limitation of custom User models is that installing a custom User model
- will break any proxy model extending :class:`~django.contrib.auth.models.User`.
- Proxy models must be based on a concrete base class; by defining a custom User
- model, you remove the ability of Django to reliably identify the base class.
- If your project uses proxy models, you must either modify the proxy to extend
- the User model that is currently in use in your project, or merge your proxy's
- behavior into your User subclass.
- Custom users and signals
- ~~~~~~~~~~~~~~~~~~~~~~~~
- Another limitation of custom User models is that you can't use
- :func:`django.contrib.auth.get_user_model()` as the sender or target of a signal
- handler. Instead, you must register the handler with the actual User model.
- Custom users and testing/fixtures
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you are writing an application that interacts with the User model, you must
- take some precautions to ensure that your test suite will run regardless of
- the User model that is being used by a project. Any test that instantiates an
- instance of User will fail if the User model has been swapped out. This
- includes any attempt to create an instance of User with a fixture.
- To ensure that your test suite will pass in any project configuration,
- ``django.contrib.auth.tests.utils`` defines a ``@skipIfCustomUser`` decorator.
- This decorator will cause a test case to be skipped if any User model other
- than the default Django user is in use. This decorator can be applied to a
- single test, or to an entire test class.
- Depending on your application, tests may also be needed to be added to ensure
- that the application works with *any* user model, not just the default User
- model. To assist with this, Django provides two substitute user models that
- can be used in test suites:
- * :class:`django.contrib.auth.tests.custom_user.CustomUser`, a custom user
- model that uses an ``email`` field as the username, and has a basic
- admin-compliant permissions setup
- * :class:`django.contrib.auth.tests.custom_user.ExtensionUser`, a custom
- user model that extends :class:`~django.contrib.auth.models.AbstractUser`,
- adding a ``date_of_birth`` field.
- You can then use the ``@override_settings`` decorator to make that test run
- with the custom User model. For example, here is a skeleton for a test that
- would test three possible User models -- the default, plus the two User
- models provided by ``auth`` app::
- from django.contrib.auth.tests.utils import skipIfCustomUser
- from django.test import TestCase
- from django.test.utils import override_settings
- class ApplicationTestCase(TestCase):
- @skipIfCustomUser
- def test_normal_user(self):
- "Run tests for the normal user model"
- self.assertSomething()
- @override_settings(AUTH_USER_MODEL='auth.CustomUser')
- def test_custom_user(self):
- "Run tests for a custom user model with email-based authentication"
- self.assertSomething()
- @override_settings(AUTH_USER_MODEL='auth.ExtensionUser')
- def test_extension_user(self):
- "Run tests for a simple extension of the built-in User."
- self.assertSomething()
- A full example
- --------------
- Here is an example of an admin-compliant custom user app. This user model uses
- an email address as the username, and has a required date of birth; it
- provides no permission checking, beyond a simple `admin` flag on the user
- account. This model would be compatible with all the built-in auth forms and
- views, except for the User creation forms.
- This code would all live in a ``models.py`` file for a custom
- authentication app::
- from django.db import models
- from django.contrib.auth.models import (
- BaseUserManager, AbstractBaseUser
- )
- class MyUserManager(BaseUserManager):
- def create_user(self, email, date_of_birth, password=None):
- """
- Creates and saves a User with the given email, date of
- birth and password.
- """
- if not email:
- raise ValueError('Users must have an email address')
- user = self.model(
- email=MyUserManager.normalize_email(email),
- date_of_birth=date_of_birth,
- )
- user.set_password(password)
- user.save(using=self._db)
- return user
- def create_superuser(self, email, date_of_birth, password):
- """
- Creates and saves a superuser with the given email, date of
- birth and password.
- """
- user = self.create_user(email,
- password=password,
- date_of_birth=date_of_birth
- )
- user.is_admin = True
- user.save(using=self._db)
- return user
- class MyUser(AbstractBaseUser):
- email = models.EmailField(
- verbose_name='email address',
- max_length=255,
- unique=True,
- db_index=True,
- )
- date_of_birth = models.DateField()
- is_active = models.BooleanField(default=True)
- is_admin = models.BooleanField(default=False)
- objects = MyUserManager()
- USERNAME_FIELD = 'email'
- REQUIRED_FIELDS = ['date_of_birth']
- def get_full_name(self):
- # The user is identified by their email address
- return self.email
- def get_short_name(self):
- # The user is identified by their email address
- return self.email
- def __unicode__(self):
- return self.email
- def has_perm(self, perm, obj=None):
- "Does the user have a specific permission?"
- # Simplest possible answer: Yes, always
- return True
- def has_module_perms(self, app_label):
- "Does the user have permissions to view the app `app_label`?"
- # Simplest possible answer: Yes, always
- return True
- @property
- def is_staff(self):
- "Is the user a member of staff?"
- # Simplest possible answer: All admins are staff
- return self.is_admin
- Then, to register this custom User model with Django's admin, the following
- code would be required in the app's ``admin.py`` file::
- from django import forms
- from django.contrib import admin
- from django.contrib.auth.models import Group
- from django.contrib.auth.admin import UserAdmin
- from django.contrib.auth.forms import ReadOnlyPasswordHashField
- from customauth.models import MyUser
- class UserCreationForm(forms.ModelForm):
- """A form for creating new users. Includes all the required
- fields, plus a repeated password."""
- password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
- password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
- class Meta:
- model = MyUser
- fields = ('email', 'date_of_birth')
- def clean_password2(self):
- # Check that the two password entries match
- password1 = self.cleaned_data.get("password1")
- password2 = self.cleaned_data.get("password2")
- if password1 and password2 and password1 != password2:
- raise forms.ValidationError("Passwords don't match")
- return password2
- def save(self, commit=True):
- # Save the provided password in hashed format
- user = super(UserCreationForm, self).save(commit=False)
- user.set_password(self.cleaned_data["password1"])
- if commit:
- user.save()
- return user
- class UserChangeForm(forms.ModelForm):
- """A form for updating users. Includes all the fields on
- the user, but replaces the password field with admin's
- password hash display field.
- """
- password = ReadOnlyPasswordHashField()
- class Meta:
- model = MyUser
- def clean_password(self):
- # Regardless of what the user provides, return the initial value.
- # This is done here, rather than on the field, because the
- # field does not have access to the initial value
- return self.initial["password"]
- class MyUserAdmin(UserAdmin):
- # The forms to add and change user instances
- form = UserChangeForm
- add_form = UserCreationForm
- # The fields to be used in displaying the User model.
- # These override the definitions on the base UserAdmin
- # that reference specific fields on auth.User.
- list_display = ('email', 'date_of_birth', 'is_admin')
- list_filter = ('is_admin',)
- fieldsets = (
- (None, {'fields': ('email', 'password')}),
- ('Personal info', {'fields': ('date_of_birth',)}),
- ('Permissions', {'fields': ('is_admin',)}),
- ('Important dates', {'fields': ('last_login',)}),
- )
- add_fieldsets = (
- (None, {
- 'classes': ('wide',),
- 'fields': ('email', 'date_of_birth', 'password1', 'password2')}
- ),
- )
- search_fields = ('email',)
- ordering = ('email',)
- filter_horizontal = ()
- # Now register the new UserAdmin...
- admin.site.register(MyUser, MyUserAdmin)
- # ... and, since we're not using Django's builtin permissions,
- # unregister the Group model from admin.
- admin.site.unregister(Group)
- .. _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 backend that checks the Django users database
- and queries the builtin permissions. It does not provide protection against
- brute force attacks via any rate limiting mechanism. You may either implement
- your own rate limiting mechanism in a custom auth backend, or use the
- mechanisms provided by most Web servers.
- 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 the duration of that session whenever access to the currently
- authenticated user is needed. This effectively means that authentication
- sources are cached on a per-session basis, 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()``.
- .. versionadded:: 1.6
- If a backend raises a :class:`~django.core.exceptions.PermissionDenied`
- exception, authentication will immediately fail. Django won't check the
- backends that follow.
- Writing an authentication backend
- ---------------------------------
- An authentication backend is a class that implements two required methods:
- ``get_user(user_id)`` and ``authenticate(**credentials)``, as well as a set of
- optional permission related :ref:`authorization methods <authorization_methods>`.
- 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(object):
- 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(object):
- 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(object):
- """
- 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
- .. _authorization_methods:
- 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(object):
- # ...
- def has_perm(self, user_obj, perm, obj=None):
- 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 in addition to the same arguments given to the associated
- :class:`django.contrib.auth.models.User` functions, the backend auth functions
- all take the user object, which may be an anonymous user, as an argument.
- A full authorization implementation can be found in the ``ModelBackend`` class
- in `django/contrib/auth/backends.py`_, which is the default backend and queries
- the ``auth_permission`` table most of the time. If you wish to provide
- custom behavior for only part of the backend API, you can take advantage of
- Python inheritence and subclass ``ModelBackend`` instead of implementing the
- complete API in a custom backend.
- .. _django/contrib/auth/backends.py: https://github.com/django/django/blob/master/django/contrib/auth/backends.py
- .. _anonymous_auth:
- Authorization for anonymous users
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 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, the user object passed to an authentication backend
- may be an :class:`django.contrib.auth.models.AnonymousUser` object, allowing
- the backend to specify custom authorization behavior 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.
- .. _inactive_auth:
- Authorization for inactive users
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- An inactive user is a one that is authenticated but has its attribute
- ``is_active`` set to ``False``. However this does not mean they are not
- authorized to do anything. For example they are allowed to activate their
- account.
- The support for anonymous users in the permission system allows for a scenario
- where anonymous users have permissions to do something while inactive
- authenticated users do not.
- Do not forget to test for the ``is_active`` attribute of the user in your own
- backend permission 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). An authentication backend will receive the keyword
- parameters ``obj`` and ``user_obj`` for each object related authorization
- method and can return the object level permission as appropriate.
|