{% raw %}
# 使用Django認證系統
這篇文檔解釋默認配置下Django認證系統的使用。這些配置已經逐步可以滿足大部分常見項目對的需要,可以處理范圍非常廣泛的任務,且具有一套細致的密碼和權限實現。對于需要與默認配置不同需求的項目,Django支持[_擴展和自定義_](customizing.html)認證。
Django的認證同時提供認證和授權,并通常統一稱為認證系統,因為這些功能某些地方是耦合的。
## User對象
[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User )對象是認證系統的核心。它們通常表示與你的站點進行交互的用戶,并用于啟用限制訪問、注冊用戶信息和關聯內容給創建者等。在Django的認證框架中只存在一種類型的用戶,因此諸如[`'superusers'`](../../ref/contrib/auth.html#django.contrib.auth.models.User.is_superuser )或管理員[`'staff'`](../../ref/contrib/auth.html#django.contrib.auth.models.User.is_staff )用戶只是具有特殊屬性集的user對象,而不是不同類型的user對象。
默認user的基本屬性有:
* [username](../../ref/contrib/auth.html#django.contrib.auth.models.User.username )
* [password](../../ref/contrib/auth.html#django.contrib.auth.models.User.password )
* [email](../../ref/contrib/auth.html#django.contrib.auth.models.User.email )
* [first_name](../../ref/contrib/auth.html#django.contrib.auth.models.User.first_name )
* [last_name](../../ref/contrib/auth.html#django.contrib.auth.models.User.last_name )
完整的參考請參閱[`full API documentation`](../../ref/contrib/auth.html#django.contrib.auth.models.User ),該文檔更偏重特定的任務。
### 創建users
創建users最直接的方法是使用[`create_user()`](../../ref/contrib/auth.html#django.contrib.auth.models.UserManager.create_user )輔助函數:
```
>>> 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.last_name = 'Lennon'
>>> user.save()
```
如果你已經安裝了Django admin,你也可以[_間接地創建users_](#auth-admin).
### 創建superusers
使用[`createsuperuser`](../../ref/django-admin.html#django-admin-createsuperuser)命令創建superusers:
```
$ python manage.py createsuperuser --username=joe --email=joe@example.com
```
將會提示你輸入一個密碼。在你輸入一個密碼后,該user將會立即創建。如果不帶[`--username`](../../ref/django-admin.html#django-admin-option---username)和[`--email`](../../ref/django-admin.html#django-admin-option---email)選項,將會提示你輸入這些值。
### 修改密碼
Django不會在user模型上存儲原始的(明文)密碼,而只是一個哈希(完整的細節參見[_文檔:密碼是如何管理的_](passwords.html))。因為這個原因,不要嘗試直接操作user的password屬性。這也是為什么創建一個user時要使用輔助函數。
若要修改一個用戶的密碼,你有幾種選擇:
[`manage.py changepassword *username*`](../../ref/django-admin.html#django-admin-changepassword)提供一種從命令行修改User密碼的方法。它提示你修改一個給定user的密碼,你必須輸入兩次。如果它們匹配,新的密碼將會立即修改。如果你沒有提供user,命令行將嘗試修改與當前系統用戶匹配的用戶名的密碼。
你也可以通過程序修改密碼,使用[`set_password()`](../../ref/contrib/auth.html#django.contrib.auth.models.User.set_password ):
```
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()
```
如果你安裝了Django admin,你還可以在[_認證系統的admin頁面_](#auth-admin)修改user的密碼。
Django還提供[_views_](#built-in-auth-views)和[_forms_](#built-in-auth-forms)用于允許user修改他們自己密碼。
New in Django 1.7\.
如果啟用了[`SessionAuthenticationMiddleware`](../../ref/middleware.html#django.contrib.auth.middleware.SessionAuthenticationMiddleware ),修改user的密碼將會登出他們所有的會話。 詳細信息請參閱[_密碼修改后會話失效_](#session-invalidation-on-password-change)。
### 認證Users
`authenticate`(_**credentials_)[[source]](../../_modules/django/contrib/auth.html#authenticate)
認證一個給定用戶名和密碼,請使用[`authenticate()`](#django.contrib.auth.authenticate )。它以關鍵字參數形式接收憑證,對于默認的配置它是`username`和`password,如果密碼對于給定的用戶名有效它將返回一個`[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User )對象。如果密碼無效,[`authenticate()`](#django.contrib.auth.authenticate )返回`None`。例子:
```
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
# the password verified for the user
if user.is_active:
print()
else:
print()
else:
# the authentication system was unable to verify the username and password
print()
```
注
這是認證一系列憑證的低級的方法;例如,它被[`RemoteUserMiddleware`](../../ref/middleware.html#django.contrib.auth.middleware.RemoteUserMiddleware )使用。除非你正在編寫你自己的認證系統,你可能不會使用到它。當然如果你在尋找一種登錄user的方法,請參見[`login_required()`](#django.contrib.auth.decorators.login_required )裝飾器。
## 權限和授權
Django從開始就帶有一個簡單的權限系統。它提供一種分配權限給特定的用戶和用戶組的方法。
它被Django的admin站點使用,但歡迎你在你自己的代碼中使用。
Django admin 站點使用如下的權限:
* 查看"add"表單并添加一個只限具有該類型對象的“add”權限的用戶對象。
* 查看修改列表、查看“change”表單以及修改一個只限具有該類型對象的“change”權限的用戶對象。
* 刪除一個只限具有該類型對象的“delete”權限的用戶對象。
權限不但可以根據每個對象的類型,而且可以根據特定的對象實例設置。通過使用[`ModelAdmin`](../../ref/contrib/admin/index.html#django.contrib.admin.ModelAdmin )類提供的[`has_add_permission()`](../../ref/contrib/admin/index.html#django.contrib.admin.ModelAdmin.has_add_permission )、[`has_change_permission()`](../../ref/contrib/admin/index.html#django.contrib.admin.ModelAdmin.has_change_permission )和[`has_delete_permission()`](../../ref/contrib/admin/index.html#django.contrib.admin.ModelAdmin.has_delete_permission )方法,可以針對相同類型的不同對象實例自定義權限。
[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User )對象具有兩個多對多的字段:`groups`和`user_permissions`。[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User )對象可以用和其它[_Django 模型_](../db/models.html)一樣的方式訪問它們相關的對象:
```
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()
```
### 默認的權限
當`django.contrib.auth`在你的[`INSTALLED_APPS`](../../ref/settings.html#std:setting-INSTALLED_APPS)設置中列出時,它將確保為你安裝的應用中的每個Django模型創建3個默認的權限 – add、change和delete。
這些權限將在你運行[`manage.py migrate`](../../ref/django-admin.html#django-admin-migrate)時創建;在添加`django.contrib.auth`到[`INSTALLED_APPS`](../../ref/settings.html#std:setting-INSTALLED_APPS)中之后,當你第一次運行`migrate`時,將會為之前安裝的模型創建默認的權限,包括與其同時正在安裝的新的模型。之后,每當你運行[`manage.py migrate`](../../ref/django-admin.html#django-admin-migrate)時,它都將為新的模型創建默認的權限。
假設你有個應用的[`app_label`](../../ref/models/options.html#django.db.models.Options.app_label )是`foo`和一個名為`Bar`的模型,要測試基本的權限,你應該使用:
* add: `user.has_perm('foo.add_bar')`
* change: `user.has_perm('foo.change_bar')`
* delete: `user.has_perm('foo.delete_bar')`
很少直接訪問[`Permission`](../../ref/contrib/auth.html#django.contrib.auth.models.Permission )模型。
### 組
[`django.contrib.auth.models.Group`](../../ref/contrib/auth.html#django.contrib.auth.models.Group )模型是用戶分類的一種通用的方式,通過這種方式你可以應用權限或其它標簽到這些用戶。一個用戶可以屬于任意多個組。
組中某個用戶自動具有賦給那個組的權限。例如,如果組`Site editors`具有權限 `can_edit_home_page`,那么該組中的任何用戶都具有該權限。
出權限之外,組還是給用戶分類的一種方便的方法以給他們某些標簽或擴展的功能。例如,你可以創建一個組`'Special users'`,然后你可以這樣寫代碼,給他們訪問你的站點僅限會員的部分,或者給他們發僅限于會員的郵件。
### 用程序創建權限
雖然[_custom permissions_](customizing.html#custom-permissions)可以定義在`Meta`類中,你還可以直接創建權限。例如,你可以為`myapp`中的`BlogPost` 創建`can_publish`權限:
```
from myapp.models import BlogPost
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(codename='can_publish',
name='Can Publish Posts',
content_type=content_type)
```
然后該權限可以通過`user_permissions`屬性分配給一個[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User ),或者通過`permissions`屬性分配給[`Group`](../../ref/contrib/auth.html#django.contrib.auth.models.Group )。
### 權限的緩存
[`ModelBackend`](../../ref/contrib/auth.html#django.contrib.auth.backends.ModelBackend )在第一次需要訪問`User`對象來檢查權限時會緩存它們的權限。這對于請求-響應循環還是比較好的,因為在權限添加進來之后并不會立即檢查(例如在admin中)。如果你正在添加權限并需要立即檢查它們,例如在一個測試或視圖中,最簡單的解決辦法是從數據庫中重新獲取`User`。 例如:
```
from django.contrib.auth.models import Permission, User
from django.shortcuts import get_object_or_404
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm('myapp.change_bar')
permission = Permission.objects.get(codename='change_bar')
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('myapp.change_bar') # False
# Request new instance of User
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm('myapp.change_bar') # True
...
```
## Web請求中的認證
Django使用[_會話_](../http/sessions.html)和中間件來攔截[`request 對象`](../../ref/request-response.html#django.http.HttpRequest )到認證系統中。
它們在每個請求上提供一個[`request.user`](../../ref/request-response.html#django.http.HttpRequest.user )屬性,表示當前的用戶。如果當前的用戶沒有登入,該屬性將設置成[`AnonymousUser`](../../ref/contrib/auth.html#django.contrib.auth.models.AnonymousUser )的一個實例,否則它將是[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User )的實例。
你可以通過[`is_authenticated()`](../../ref/contrib/auth.html#django.contrib.auth.models.User.is_authenticated )區分它們,像這樣:
```
if request.user.is_authenticated():
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
```
### 如何登入一個用戶
如果你有一個認證了的用戶,你想把它附帶到當前的會話中 - 這可以通過[`login()`](#django.contrib.auth.login )函數完成。
`login`()[[source]](../../_modules/django/contrib/auth.html#login)
從視圖中登入一個用戶,請使用[`login()`](#django.contrib.auth.login )。它接受一個[`HttpRequest`](../../ref/request-response.html#django.http.HttpRequest )對象和一個[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User )對象。[`login()`](#django.contrib.auth.login )使用Django的會話框架保存用戶的ID在會話中。
注意任何在匿名會話中設置的數據都會在用戶登入后的會話中都會記住。
這個例子展示你可能如何使用[`authenticate()`](#django.contrib.auth.authenticate )和 [`login()`](#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.
...
```
先調用`authenticate()`:
當你是手工登入一個用戶時,你_必須_在調用[`login()`](#django.contrib.auth.login )之前通過[`authenticate()`](#django.contrib.auth.authenticate )成功地認證該用戶。[`authenticate()`](#django.contrib.auth.authenticate )在[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User )上設置一個屬性標識哪種認證后臺成功認證了該用戶(細節參見[_后臺的文檔_](customizing.html#authentication-backends)),且該信息在后面登錄的過程中是需要的。如果你視圖登入一個直接從數據庫中取出的用戶,將會拋出一個錯誤。
### 如何登出一個用戶
`logout`()[[source]](../../_modules/django/contrib/auth.html#logout)
若要登出一個已經通過[`django.contrib.auth.login()`](#django.contrib.auth.login )登入的用戶,可以在你的視圖中使用[`django.contrib.auth.logout()`](#django.contrib.auth.logout )。 它接收一個[`HttpRequest`](../../ref/request-response.html#django.http.HttpRequest )對象且沒有返回值。例如:
```
from django.contrib.auth import logout
def logout_view(request):
logout(request)
# Redirect to a success page.
```
注意,即使用戶沒有登入[`logout()`](#django.contrib.auth.logout )也不會拋出任何錯誤。
當你調用[`logout()`](#django.contrib.auth.logout )時,當前請求的會話數據將被完全清除。所有存在的數據都將清除。這是為了防止另外一個人使用相同的Web瀏覽器登入并訪問前一個用戶的會話數據。如果你想在用戶登出之后>可以立即訪問放入會話中的數據,請在調用[`django.contrib.auth.logout()`](#django.contrib.auth.logout )_之后_放入。
### 限制訪問給登陸后的用戶
#### 原始的方法
限制頁面訪問的簡單、原始的方法是檢查[`request.user.is_authenticated()`](../../ref/contrib/auth.html#django.contrib.auth.models.User.is_authenticated )并重定向到一個登陸頁面:
```
from django.conf import settings
from django.shortcuts import redirect
def my_view(request):
if not request.user.is_authenticated():
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
# ...
```
...或者顯示一個錯誤信息:
```
from django.shortcuts import render
def my_view(request):
if not request.user.is_authenticated():
return render(request, 'myapp/login_error.html')
# ...
```
#### login_required 裝飾器
`login_required`([_redirect_field_name=REDIRECT_FIELD_NAME_, _login_url=None_])[[source]](../../_modules/django/contrib/auth/decorators.html#login_required)
作為一個快捷方式,你可以使用便捷的[`login_required()`](#django.contrib.auth.decorators.login_required )裝飾器:
```
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
```
[`login_required()`](#django.contrib.auth.decorators.login_required )完成下面的事情:
* 如果用戶沒有登入,則重定向到[settings.LOGIN_URL](../../ref/settings.html#std:setting-LOGIN_URL),并傳遞當前查詢字符串中的絕對路徑。例如:`/accounts/login/?next=/polls/3/`。
* 如果用戶已經登入,則正常執行視圖。視圖的代碼可以安全地假設用戶已經登入。
默認情況下,在成功認證后用戶應該被重定向的路徑存儲在查詢字符串的一個叫做`)帶有一個可選的`redirect_field_name`參數:
```
from django.contrib.auth.decorators import login_required
@login_required(redirect_field_name='my_redirect_field')
def my_view(request):
...
```
注意,如果你提供一個值給`redirect_field_name`,你非常可能同時需要自定義你的登錄模板,因為存儲重定向路徑的模板上下文變量將使用`redirect_field_name`值作為它的鍵,而不是默認的`"next"`。
[`login_required()`](#django.contrib.auth.decorators.login_required )還帶有一個可選的`login_url`參數。例如:
```
from django.contrib.auth.decorators import login_required
@login_required(login_url='/accounts/login/')
def my_view(request):
...
```
注意,如果你沒有指定`login_url`參數,你需要確保[`settings.LOGIN_URL`](../../ref/settings.html#std:setting-LOGIN_URL)并且你的登錄視圖正確關聯。例如,使用默認值,可以添加下面幾行到你的URLconf中:
```
from django.contrib.auth import views as auth_views
url(r'^accounts/login/$', auth_views.login),
```
[`settings.LOGIN_URL`](../../ref/settings.html#std:setting-LOGIN_URL)同時還接收視圖函數名和[_命名的URL模式_](../http/urls.html#naming-url-patterns)。這允許你自由地重新映射你的URLconf中的登錄視圖而不用更新設置。
注
login_required裝飾器不檢查user的is_active標志位。
#### 給已驗證登錄的用戶添加訪問限制
基于特定的權限和其他方式來限制訪問,你最好按照前面所敘述的那樣操做。
簡單的方法就是在視圖中直接運行你對[`request.user`](../../ref/request-response.html#django.http.HttpRequest.user )的測試。例如,視圖檢查用戶的郵件屬于特定的地址(例如@example.com),若不是,則重定向到登錄頁面。
```
from django.shortcuts import redirect
def my_view(request):
if not request.user.email.endswith('@example.com'):
return redirect('/login/?next=%s' % request.path)
# ...
```
`user_passes_test`(_func_[, _login_url=None_, _redirect_field_name=REDIRECT_FIELD_NAME_])[[source]](../../_modules/django/contrib/auth/decorators.html#user_passes_test)
你可以用方便的 `user_passes_test` 裝飾器,當回掉函數返回 `False` 時會執行一個重定向操作:
```
from django.contrib.auth.decorators import user_passes_test
def email_check(user):
return user.email.endswith('@example.com')
@user_passes_test(email_check)
def my_view(request):
...
```
[`user_passes_test()`](#django.contrib.auth.decorators.user_passes_test ) 要求一個以[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User ) 對象為參數的回掉函數,若用戶允許訪問此視圖,返回 `True`。注意,[`user_passes_test()`](#django.contrib.auth.decorators.user_passes_test ) 不會自動檢查 [`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User ) 是否是不是匿名對象。
[`user_passes_test()`](#django.contrib.auth.decorators.user_passes_test )接收兩個額外的參數:
`login_url`
讓你指定那些沒有通過檢查的用戶要重定向至哪里。若不指定其值,它可能是默認的 [`settings.LOGIN_URL`](../../ref/settings.html#std:setting-LOGIN_URL)。
`redirect_field_name`
與[`login_required()`](#django.contrib.auth.decorators.login_required )的參數相同。把它設置為 `None` 來把它從 URL 中移除,當你想把通不過檢查的用戶重定向到沒有next page 的非登錄頁面時。
例如:
```
@user_passes_test(email_check, login_url='/login/')
def my_view(request):
...
```
#### permission_required 裝飾器
`permission_required`(_perm_[, _login_url=None_, _raise_exception=False_])[[source]](../../_modules/django/contrib/auth/decorators.html#permission_required)
檢查一個用戶是否有指定的權限是相對常見的需求。因此,Django 提供了一個快捷方式: [`permission_required()`](#django.contrib.auth.decorators.permission_required ) 裝飾器:
```
from django.contrib.auth.decorators import permission_required
@permission_required('polls.can_vote')
def my_view(request):
...
```
[`has_perm()`](../../ref/contrib/auth.html#django.contrib.auth.models.User.has_perm ) 方法, 權限名稱采用如下方法 `"<app label>.<permission codename>"` (例如 `polls.can_vote` 表示在 `polls` 應用下一個模塊的權限。
要注意[`permission_required()`](#django.contrib.auth.decorators.permission_required ) 也接受一個可選的`login_url`參數。例如:
```
from django.contrib.auth.decorators import permission_required
@permission_required('polls.can_vote', login_url='/loginpage/')
def my_view(request):
...
```
在 [`login_required()`](#django.contrib.auth.decorators.login_required ) 裝飾器中, `login_url`默認為[`settings.`](../../ref/settings.html#std:setting-LOGIN_URL)LOGIN_URL。
如果提供了 `raise_exception` 參數,裝飾器拋出[`PermissionDenied`](../../ref/exceptions.html#django.core.exceptions.PermissionDenied )異常,使用 [_the 403 (HTTP Forbidden) 視圖_](../../ref/views.html#http-forbidden-view)而不是重定向到登錄頁面。
Changed in Django 1.7:
[`permission_required()`](#django.contrib.auth.decorators.permission_required )裝飾器既可以接收一個權限序列也可以接收一個單個的權限。
#### 對普通的視圖使用權限
若要對一個[_基于類的普通視圖_](../../ref/class-based-views/index.html)使用權限,可以在該類上裝飾[`View.dispatch`](../../ref/class-based-views/base.html#django.views.generic.base.View.dispatch )方法。詳細細節參見[_Decorating the class_](../class-based-views/intro.html#id2)。 另外一個方法是[_編寫一個封裝as_view()的mixin_](../class-based-views/intro.html#mixins-that-wrap-as-view)。
#### 密碼更改后的會話失效
New in Django 1.7\.
警告
這種保護只在[`MIDDLEWARE_CLASSES`](../../ref/settings.html#std:setting-MIDDLEWARE_CLASSES)中[`SessionAuthenticationMiddleware`](../../ref/middleware.html#django.contrib.auth.middleware.SessionAuthenticationMiddleware )開啟的情況下應用。如果`settings.py`由Django ≥ 1.7\. 的[`startproject`](../../ref/django-admin.html#django-admin-startproject)生成,它會被包含進來。
在Django 2.0中,會話驗證會變成強制性的, 無論是否開啟了`SessionAuthenticationMiddleware` 。 如果你擁有一個1.7之前的項目,或者使用不包含`SessionAuthenticationMiddleware`的模板生成的項目,考慮在閱讀下面的升級說明之后開啟它。
如果你的[`AUTH_USER_MODEL`](../../ref/settings.html#std:setting-AUTH_USER_MODEL)繼承自[`AbstractBaseUser`](customizing.html#django.contrib.auth.models.AbstractBaseUser ),或者實現了它自己的[`get_session_auth_hash()`](customizing.html#django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash )方法,驗證后的會話會包含這個函數返回的哈希值。在[`AbstractBaseUser`](customizing.html#django.contrib.auth.models.AbstractBaseUser)的情況中,這是密碼字段的HMAC。如果開啟了[`SessionAuthenticationMiddleware`](../../ref/middleware.html#django.contrib.auth.middleware.SessionAuthenticationMiddleware) ,Django會驗證每個請求帶有的哈希值是否匹配服務端計算出來的哈希值。這允許用戶通過修改密碼來登出所有的會話。
Django中包含的默認的密碼修改視圖,以及[`django.contrib.auth`](index.html#module-django.contrib.auth)中的 [`django.contrib.auth.views.password_change()`](#django.contrib.auth.views.password_change )和`user_change_password`視圖 ,會使用新的密碼哈希值升級會話,以便用戶在修改密碼是不會登出。如果你擁有自定義的密碼修改視圖,并且希望具有相似的行為,使用這個函數:
`update_session_auth_hash`(_request_, _user_)
這個函數接受當前請求,并且會在會話哈希值得到的地方升級用戶對象,也會適當地升級會話哈希值。使用示例:
```
from django.contrib.auth import update_session_auth_hash
def password_change(request):
if request.method == 'POST':
form = PasswordChangeForm(user=request.user, data=request.POST)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
else:
...
```
如果你在升級一個現存的站點,并且希望開啟這一中間件,而不希望你的所有用戶之后重新登錄,你可以首先升級到DJango1.7并且運行它一段時間,以便所有會話在用戶登錄時自然被創建,它們包含上面描述的會話哈希。一旦你使用[`SessionAuthenticationMiddleware`](../../ref/middleware.html#django.contrib.auth.middleware.SessionAuthenticationMiddleware )開始運行你的站點,任何沒有登錄并且會話使用驗證哈希值升級過的用戶的現有會話都會失效,并且需要重新登錄。
注意
雖然[`get_session_auth_hash()`](customizing.html#django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash )給予[`SECRET_KEY`](../../ref/settings.html#std:setting-SECRET_KEY),使用新的私鑰升級你的站點會使所有現有會話失效。
### 認證的視圖
Django提供一些視圖,你可以用來處理登錄、登出和密碼管理。它們使用[_stock auth 表單_](#built-in-auth-forms),但你也可以傳遞你自己的表單。
Django沒有為認證視圖提供默認的模板。你應該為你想要使用的視圖創建自己的模板。模板的上下文定義在每個視圖中,參見[_所有的認證視圖_](#all-authentication-views).
#### 使用視圖
有幾種不同的方法在你的項目中使用這些視圖。最簡單的方法是包含`django.contrib.auth.urls`中提供的URLconf到你自己的URLconf中,例如
```
urlpatterns = [
url('^', include('django.contrib.auth.urls'))
]
```
這將包含進下面的URL模式:
```
^login/$ [name='login']
^logout/$ [name='logout']
^password_change/$ [name='password_change']
^password_change/done/$ [name='password_change_done']
^password_reset/$ [name='password_reset']
^password_reset/done/$ [name='password_reset_done']
^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
^reset/done/$ [name='password_reset_complete']
```
這些視圖提供了一個簡單易記的URL名稱。使用命名URL模式的細節請參見[_URL文檔_](../http/urls.html)。
如果你想更多地控制你的URL,你可以在你的URLconf中引用一個特定的視圖:
```
urlpatterns = [
url('^change-password/', 'django.contrib.auth.views.password_change')
]
```
這些視圖具有可選的參數,你可以用來改變視圖的行為。例如,如果你想修改一個視圖使用的模板名稱,你可以提供`template_name`參數。實現它的一種方法是在URLconf中提供一個關鍵字參數,它們將被傳遞到視圖中。例如:
```
urlpatterns = [
url(
'^change-password/',
'django.contrib.auth.views.password_change',
{'template_name': 'change-password.html'}
)
]
```
所有的視圖都返回一個[`TemplateResponse`](../../ref/template-response.html#django.template.response.TemplateResponse ) 實例,這允許你在渲染之前很容易自定義響應。實現它的一種方法是在你自己的視圖中包裝一個視圖:
```
from django.contrib.auth import views
def change_password(request):
template_response = views.password_change(request)
# Do something with `template_response`
return template_response
```
更多的細節,參見[_TemplateResponse文檔_](../../ref/template-response.html)。
#### 所有的認證視圖
下面列出了`django.contrib.auth`提供的所有視圖。實現細節參見[_使用視圖_](#using-the-views)。
`login`(_request_[, _template_name_, _redirect_field_name_, _authentication_form_, _current_app_, _extra_context_])[[source]](../../_modules/django/contrib/auth/views.html#login)
**URL 名稱:**`login`
關于使用命名URL模式的細節參見[_URL 文檔_](../http/urls.html)。
**可選的參數:**
* `template_name`: 用于用戶登錄視圖的模板名。默認為`registration/login.html`。
* `redirect_field_name`: `GET`字段的名稱,包含登陸后重定向URL。默認為`next`。
* `authentication_form`: 用于認證的可調用對象(通常只是一個表單類)。默認為[AuthenticationForm](#django.contrib.auth.forms.AuthenticationForm )。
* `current_app`: 指示包含當前視圖的是哪個應用。更多信息參見[命名URL的解析策略](../http/urls.html#topics-http-reversing-url-namespaces)。
* `extra_context`: 一個上下文數據的字典,將被添加到傳遞給模板的默認上下文數據中。
下面是`django.contrib.auth.views.login`所做的事情:
* 如果通過 `GET`調用,它顯示一個POST給相同URL的登錄表單。后面有更多這方面的信息。
* 如果通過`POST`調用并帶有用戶提交的憑證,它會嘗試登入該用戶。如果登入成功,該視圖重定向到`next`中指定的URL。如果`next`沒有提供,它重定向到[settings.LOGIN_REDIRECT_URL](../../ref/settings.html#std:setting-LOGIN_REDIRECT_URL)(默認為`/accounts/profile/`)。如果登入不成功,則重新顯示登錄表單。
你需要提供html模板給login,默認調用`registration/login.html`。模板會得到4個模板上下文變量:
* `form`: 一個表示[AuthenticationForm](#django.contrib.auth.forms.AuthenticationForm )的[Form](../../ref/forms/api.html#django.forms.Form )對象。
* `next`: 登入成功之后重定向的URL。它還可能包含一個查詢字符串。
* `site`: 如果你沒有安裝site框架,這將被設置成[RequestSite](../../ref/contrib/sites.html#django.contrib.sites.requests.RequestSite )的一個實例,它從當前的[HttpRequest](../../ref/request-response.html#django.http.HttpRequest )獲得site名稱和域名。
* `site_name`: `site.name`的別名。如果你沒有安裝site框架,這將被設置成[request.META['SERVER_NAME']](../../ref/request-response.html#django.http.HttpRequest.META )的值。關于site 的更多信息,參見[_“sites” 框架_](../../ref/contrib/sites.html)。
如果你不喜歡調用`registration/login.html`,你可以通過額外的參數傳遞`template_name`參數給你URLconf中的視圖。例如,下面URLconf中的行將使用`myapp/login.html`:
```
url(r'^accounts/login/$', auth_views.login, {'template_name': 'myapp/login.html'}),
```
通過傳遞`redirect_field_name`給視圖,你還可以指定`GET`字段的值,它包含登入成功后的重定向的URL。默認情況下,該字段叫做`next`。
下面是一個`registration/login.html`模板的示例,你可以用它來作為起點。它假設你有一個定義了`content`塊的`base.html`模板:
```
{% 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 %}
```
如果你自定義認證(參見[_Customizing Authentication_](customizing.html)),你可以通過`authentication_form`參數傳遞一個自定義的認證表單給登錄視圖。該表單必須在它的`__init__`方法中接收一個`request`關鍵字參數,并提供一個`get_user`方法,此方法返回認證過的用戶對象(這個方法永遠只在表單驗證成功后調用)。
`logout`(_request_[, _next_page_, _template_name_, _redirect_field_name_, _current_app_, _extra_context_])[[source]](../../_modules/django/contrib/auth/views.html#logout)
登出一個用戶。
**URL名稱:**`logout`
**可選的參數:**
* `next_page`: 登出之后要重定向的URL。
* `template_name`: 用戶登出之后,要展示的模板的完整名稱。如果不提供任何參數,默認為`registration/logged_out.html`。
* `redirect_field_name`: 包含登出之后所重定向的URL的`GET`字段的名稱。默認為 `next`。如果提供了`GET`參數,會覆蓋`next_page` URL。
* `current_app`: 一個提示,表明哪個應用含有了當前視圖。 詳見 [命名空間下的URL解析策略](../http/urls.html#topics-http-reversing-url-namespaces) 。
* `extra_context`: 一個上下文數據的字典,會被添加到向模板傳遞的默認的上下文數據中。
**模板上下文:**
* `title`: 本地化的字符串“登出”。
* `site`: 根據[SITE_ID](../../ref/settings.html#std:setting-SITE_ID) 設置的當前[站點](../../ref/contrib/sites.html#django.contrib.sites.models.Site )。如果你并沒有安裝站點框架,會設置為 [RequestSite](../../ref/contrib/sites.html#django.contrib.sites.requests.RequestSite )的示例,它從當前[HttpRequest](../../ref/request-response.html#django.http.HttpRequest )來獲取站點名稱和域名。
* `site_name`: `site.name`的別名。如果沒有安裝站點框架,會設置為[request.META['SERVER_NAME']](../../ref/request-response.html#django.http.HttpRequest.META )。站點的更多信息請見[_“站點”框架_](../../ref/contrib/sites.html)。
* `current_app`: 一個提示,表明哪個應用含有了當前視圖。 詳見 [命名空間下的URL解析策略](../http/urls.html#topics-http-reversing-url-namespaces) 。
* `extra_context`: 一個上下文數據的字典,會被添加到向模板傳遞的默認的上下文數據中。
`logout_then_login`(_request_[, _login_url_, _current_app_, _extra_context_])[[source]](../../_modules/django/contrib/auth/views.html#logout_then_login)
登出一個用戶,然后重定向到登錄頁面。
**URL 名稱:** 沒有提供默認的URL
**可選的參數:**
* `login_url`: 登錄頁面要重定向的URL。如果沒有提供,默認為[settings.LOGIN_URL](../../ref/settings.html#std:setting-LOGIN_URL)。
* `current_app`: 一個提示,表明哪個應用含有了當前視圖。詳見 [命名空間下的URL解析策略](../http/urls.html#topics-http-reversing-url-namespaces) 。
* `extra_context`: 一個上下文數據的字典,會被添加到向模板傳遞的默認的上下文數據中。
`password_change`(_request_[, _template_name_, _post_change_redirect_, _password_change_form_, _current_app_, _extra_context_])[[source]](../../_modules/django/contrib/auth/views.html#password_change)
允許一個用戶修改他的密碼。
**URL 名稱:**`password_change`
**可選的參數:**
* `template_name`: 用來顯示修改密碼表單的template的全名。如果沒有提供,默認為`registration/password_change_form.html` 。
* `post_change_redirect`: 密碼修改成功后重定向的URL。
* `password_change_form`: 一個自定義的“修改密碼”表單,必須接受`user` 關鍵詞參數。表單用于實際修改用戶密碼。默認為 [PasswordChangeForm](#django.contrib.auth.forms.PasswordChangeForm )。
* `current_app`: 一個提示,暗示哪個應用包含當前的視圖。詳見 [命名空間下的URL解析策略](../http/urls.html#topics-http-reversing-url-namespaces) 。
* `extra_context`: 上下文數據的字典,會添加到傳遞給模板的默認的上下文數據中。
**模板上下文:**
* `form`: 密碼修改表單(請見上面的`password_change_form`)。
`password_change_done`(_request_[, _template_name_, _current_app_, _extra_context_])[[source]](../../_modules/django/contrib/auth/views.html#password_change_done)
這個頁面在用戶修改密碼之后顯示。
**URL 名稱:**`password_change_done`
**可選參數:**
* `template_name`: 所使用模板的完整名稱。如果沒有提供,默認為`registration/password_change_done.html`。
* `current_app`: 一個提示,暗示哪個應用包含當前的視圖。 詳見 [命名空間下的URL解析策略](../http/urls.html#topics-http-reversing-url-namespaces) 。
* `extra_context`: 上下文數據的字典,會添加到傳遞給模板的默認的上下文數據中。
`password_reset`(_request_[, _is_admin_site_, _template_name_, _email_template_name_, _password_reset_form_, _token_generator_, _post_reset_redirect_, _from_email_, _current_app_, _extra_context_, _html_email_template_name_])[[source]](../../_modules/django/contrib/auth/views.html#password_reset)
允許用戶通過生成一次性的連接并發送到用戶注冊的郵箱地址中來重置密碼。
如果提供的郵箱地址不在系統中存在,這個視圖不會發送任何郵件,但是用戶也不會收到任何錯誤信息。這會阻止數據泄露給潛在的攻擊者。如果你打算在這種情況提供錯誤信息,你可以繼承[`PasswordResetForm`](#django.contrib.auth.forms.PasswordResetForm ),并使用`password_reset_form` 參數。
用無效密碼標記的用戶(參見[`set_unusable_password()`](../../ref/contrib/auth.html#django.contrib.auth.models.User.set_unusable_password ))不允許請求重置密碼,為了防止使用類似于LDAP的外部驗證資源時的濫用。注意它們不會收到任何錯誤信息,因為這會暴露它們的賬戶,也不會發送任何郵件。
**URL 名稱:**`password_reset`
**可選參數:**
* `template_name`: The full name of a template to use for
displaying the password reset form. Defaults to
`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
`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 `registration/password_reset_subject.txt` if not supplied.
* `password_reset_form`: Form that will be used to get the email of
the user to reset the password for. Defaults to
[{{s.379}}](#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 [DEFAULT_FROM_EMAIL](../../ref/settings.html#std:setting-DEFAULT_FROM_EMAIL).
* `current_app`: A hint indicating which application contains the current
view. See the [{{s.385}}](../http/urls.html#topics-http-reversing-url-namespaces) for more information.
* `extra_context`: A dictionary of context data that will be added to the
default context data passed to the template.
* `html_email_template_name`: The full name of a template to use
for generating a `text/html` multipart email with the password reset
link. By default, HTML email is not sent.
New in Django 1.7:
添加了`html_email_template_name`。
Deprecated since version 1.8: `is_admin_site`參數已被廢棄,將在Django2.0中被移除。
**模板上下文:**
* `form`: The form (see `password_reset_form` above) for resetting
the user’s password.
**Email模板上下文:**
* `email`: An alias for `user.email`
* `user`: The current [User](../../ref/contrib/auth.html#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
[request.META['SERVER_NAME']](../../ref/request-response.html#django.http.HttpRequest.META ).
For more on sites, see [_The “sites” framework_](../../ref/contrib/sites.html).
* `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 primary key encoded in base 64.
* `token`: Token to check that the reset link is valid.
`registration/password_reset_email.html`樣例(郵件正文模板):
```
Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
```
主題模板使用了同樣的模板上下文。主題必須是單行的純文本字符串。
`password_reset_done`(_request_[, _template_name_, _current_app_, _extra_context_])[[source]](../../_modules/django/contrib/auth/views.html#password_reset_done)
這個頁面在向用戶發送重置密碼的郵件后展示。如果[`password_reset()`](#django.contrib.auth.views.password_reset )視圖沒有顯式設置 `post_reset_redirect`URL,默認會調用這個視圖。
**URL名稱:**`password_reset_done`
注意
如果提供的email地址在系統中不存在,用戶未激活,或者密碼不可用,用戶仍然會重定向到這個視圖,但是不會發送郵件。
**可選參數:**
* `template_name`: The full name of a template to use.
Defaults to `registration/password_reset_done.html` if not
supplied.
* `current_app`: A hint indicating which application contains the current
view. See the [{{s.393}}](../http/urls.html#topics-http-reversing-url-namespaces) for more information.
* `extra_context`: A dictionary of context data that will be added to the
default context data passed to the template.
`password_reset_confirm`(_request_[, _uidb64_, _token_, _template_name_, _token_generator_, _set_password_form_, _post_reset_redirect_, _current_app_, _extra_context_])[[source]](../../_modules/django/contrib/auth/views.html#password_reset_confirm)
為輸入新密碼展示表單。
**URL名稱:**`password_reset_confirm`
**可選參數:**
* `uidb64`: The user’s id encoded in base 64\. 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 `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 [{{s.395}}](#django.contrib.auth.forms.SetPasswordForm )
* `post_reset_redirect`: URL to redirect after the password reset
done. Defaults to `None`.
* `current_app`: A hint indicating which application contains the current
view. See the [{{s.400}}](../http/urls.html#topics-http-reversing-url-namespaces) for more information.
* `extra_context`: A dictionary of context data that will be added to the
default context data passed to the template.
**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 `uidb64` and
`token`) is valid or unused yet.
`password_reset_complete`(_request_[, _template_name_, _current_app_, _extra_context_])[[source]](../../_modules/django/contrib/auth/views.html#password_reset_complete)
展示一個視圖,它通知用戶密碼修改成功。
**URL名稱:**`password_reset_complete`
**可選參數:**
* `template_name`: The full name of a template to display the view.
Defaults to `registration/password_reset_complete.html`.
* `current_app`: A hint indicating which application contains the current
view. See the [{{s.403}}](../http/urls.html#topics-http-reversing-url-namespaces) for more information.
* `extra_context`: A dictionary of context data that will be added to the
default context data passed to the template.
### 輔助函數
`redirect_to_login`(_next_[, _login_url_, _redirect_field_name_])[[source]](../../_modules/django/contrib/auth/views.html#redirect_to_login)
重定向到登錄頁面,然后在登入成功后回到另一個URL。
**必需的參數:**
* `next`: The URL to redirect to after a successful login.
**可選的參數:**
* `login_url`: The URL of the login page to redirect to.
Defaults to [{{s.411}}](../../ref/settings.html#std:setting-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.
### 內建的表單
如果你不想用內建的視圖,但是又不想編寫針對該功能的表單,認證系統提供了幾個內建的表單,位于[`django.contrib.auth.forms`](#module-django.contrib.auth.forms ):
注
內建的驗證表單對他們處理的用戶模型做了特定假設。如果你使用了[_自定義的用戶模型_](customizing.html#auth-custom-user),可能需要為驗證系統定義你自己的表單。更多信息請見 [_使用帶有自定義用戶模型的內建驗證表單_](customizing.html#custom-users-and-the-built-in-auth-forms)的文檔。
_class _`AdminPasswordChangeForm`[[source]](../../_modules/django/contrib/auth/forms.html#AdminPasswordChangeForm)
管理界面中使用的表單,用于修改用戶密碼。
接受`user`作為第一個參數。
_class _`AuthenticationForm`[[source]](../../_modules/django/contrib/auth/forms.html#AuthenticationForm)
用于用戶登錄的表單。
接受`request` 作為第一個參數,它儲存在表單實例中,被子類使用。
`confirm_login_allowed`(_user_)[[source]](../../_modules/django/contrib/auth/forms.html#AuthenticationForm.confirm_login_allowed)
New in Django 1.7\.
通常, `AuthenticationForm`會拒絕 `is_active`標志是`False`的用戶。你可以使用自定義政策覆蓋這一行為,來決定哪些用戶可以登錄。使用一個繼承 `AuthenticationForm`并覆寫`confirm_login_allowed`方法的自定義表單來實現它。如果提供的用戶不能登錄,這個方法應該拋出[`ValidationError`](../../ref/exceptions.html#django.core.exceptions.ValidationError )異常。
例如,允許所有用戶登錄,不管“活動”狀態如何:
```
from django.contrib.auth.forms import AuthenticationForm
class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
def confirm_login_allowed(self, user):
pass
```
或者只允許一些活動用戶登錄進來:
```
class PickyAuthenticationForm(AuthenticationForm):
def confirm_login_allowed(self, user):
if not user.is_active:
raise forms.ValidationError(
_(),
code='inactive',
)
if user.username.startswith('b'):
raise forms.ValidationError(
_(),
code='no_b_users',
)
```
_class _`PasswordChangeForm`[[source]](../../_modules/django/contrib/auth/forms.html#PasswordChangeForm)
一個表單,允許用戶修改他們的密碼。
_class _`PasswordResetForm`[[source]](../../_modules/django/contrib/auth/forms.html#PasswordResetForm)
一個表單,用于生成和通過郵件發送一次性密碼重置鏈接。
`send_email`(_subject_template_name_, _email_template_name_, _context_, _from_email_, _to_email_[, _html_email_template_name=None_])
New in Django 1.8\.
使用參數來發送`EmailMultiAlternatives`。可以覆蓋來自定義郵件如何發送給用戶。
<table class="docutils field-list" frame="void" rules="none"><colgroup><col class="field-name"><col class="field-body"></colgroup><tbody valign="top"><tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body">* **subject_template_name** – the template for the subject.
* **email_template_name** – the template for the email body.
* **context** – context passed to the `subject_template`, `email_template`,
and `html_email_template` (if it is not `None`).
* **from_email** – the sender’s email.
* **to_email** – the email of the requester.
* **html_email_template_name** – the template for the HTML body;
defaults to `None`, in which case a plain text email is sent.
</td></tr></tbody></table>
通常, `save()` 位于`context`中,并帶有 [`password_reset()`](#django.contrib.auth.views.password_reset ) 向它的email上下文傳遞的一些變量。
_class _`SetPasswordForm`[[source]](../../_modules/django/contrib/auth/forms.html#SetPasswordForm)
允許用戶不輸入舊密碼修改密碼的表單。
_class _`UserChangeForm`[[source]](../../_modules/django/contrib/auth/forms.html#UserChangeForm)
用戶管理界面中修改用戶信息和許可的表單。
_class _`UserCreationForm`[[source]](../../_modules/django/contrib/auth/forms.html#UserCreationForm)
用于創建新用戶的表單。
### 模板中的認證數據
當你使用[`RequestContext`](../../ref/templates/api.html#django.template.RequestContext )時,當前登入的用戶和它們的權限在[_模板上下文_](../../ref/templates/api.html)中可以訪問。
技術細節
技術上講,這些變量只有在你使用[`RequestContext`](../../ref/templates/api.html#django.template.RequestContext )并啟用了`'django.contrib.auth.context_processors.auth'`上下文處理器時才可以在模板上下文中訪問到。它是默認產生的配置文件。更多信息,參見[_RequestContext 文檔_](../../ref/templates/api.html#subclassing-context-requestcontext)。
#### 用戶
當渲染[`RequestContext`](../../ref/templates/api.html#django.template.RequestContext )模板時,當前登錄的用戶,可能是[`User`](../../ref/contrib/auth.html#django.contrib.auth.models.User )實例或者[`AnonymousUser`](../../ref/contrib/auth.html#django.contrib.auth.models.AnonymousUser )實例,會存儲在模板變量`{{ user }}`中:
```
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
```
如果使用的不是`RequestContext`,則不可以訪問該模板變量:
#### 權限
當前登錄的用戶的權限存儲在模板變量`{{ perms }}`中。這是個 `django.contrib.auth.context_processors`實例的封裝,他是一個對于模板友好的權限代理。
在`{{ perms }}` 對象中,單一屬性的查找是 [`User.has_module_perms`](../../ref/contrib/auth.html#django.contrib.auth.models.User.has_module_perms )的代理。如果已登錄的用戶在`foo` 應用中擁有任何許可,這個例子會顯示 `True`:
```
{{ perms.foo }}
```
二級屬性的查找是[`User.has_perm`](../../ref/contrib/auth.html#django.contrib.auth.models.User.has_perm )的代理。如果已登錄的用戶擁有`foo.can_vote`的許可,這個示例會顯示`True`:
```
{{ perms.foo.can_vote }}
```
所以,你可以用模板的`{% if %}`語句檢查權限:
```
{% 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 %}
```
還可以通過`{% if in %}`語句查詢權限。例如:
```
{% if 'foo' in perms %}
{% if 'foo.can_vote' in perms %}
<p>In lookup works, too.</p>
{% endif %}
{% endif %}
```
## 在admin中管理用戶
如果`django.contrib.admin`和`django.contrib.auth`這兩個你都安裝了,將可以通過admin方便地查看和管理用戶、組和權限。可以像其它任何Django模型一樣創建和刪除用戶。可以創建組,并分配權限給用戶和組。admin中還會保存和顯示對用戶模型編輯的日志。
### 創建用戶
在admin的主頁,你應該可以在“Auth”部分看到“Users”鏈接。“Add user” 頁面與標準admin頁面不同點在于它要求你在編輯用戶的其它字段之前先選擇一個用戶名和密碼。
另請注意:如果你想使得一個用戶能夠使用Django的admin站點創建其它用戶, 你需要給他添加用戶_和_修改用戶的權限(例如,"Add user” 和“Change user” 權限)。如果一個賬號具有添加用戶的權限但是沒有權限修改他們,該賬號將不能添加用戶。為什么呢?因為如果你具有添加用戶的權限,你將可以添加超級用戶,這些超級用戶將可以修改其他用戶。所以Django同時要求添加權限_和_修改權限作為一種輕量的安全措施。
仔細考慮一下你是如何允許用戶管理權限的。如果你了一個非超級用戶編輯用戶的能力,這和給他們超級用戶的權限在最終效果上是一樣的,因為他們將能夠提升他們自己下面的用戶的權限。
### 修改密碼
用戶密碼不會顯示在admin上(也不會存儲在數據庫中),但是會顯示 [_密碼存儲的細節_](passwords.html)。 這個信息的顯示中包含一條指向修改密碼表單的鏈接,允許管理員修改用戶的密碼。
> 譯者:[Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html),原文:[Using the authentication system ](https://docs.djangoproject.com/en/1.8/topics/auth/default/)。
>
> 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 協議發布,轉載請保留作者署名和文章出處。
>
> [Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html)人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
{% endraw %}
- 新手入門
- 從零開始
- 概覽
- 安裝
- 教程
- 第1部分:模型
- 第2部分:管理站點
- 第3部分:視圖和模板
- 第4部分:表單和通用視圖
- 第5部分:測試
- 第6部分:靜態文件
- 高級教程
- 如何編寫可重用的應用
- 為Django編寫首個補丁
- 模型層
- 模型
- 模型語法
- 元選項
- 模型類
- 查詢集
- 執行查詢
- 查找表達式
- 模型的實例
- 實例方法
- 訪問關聯對象
- 遷移
- 模式編輯器
- 編寫遷移
- 高級
- 管理器
- 原始的SQL查詢
- 聚合
- 多數據庫
- 自定義查找
- 條件表達式
- 數據庫函數
- 其它
- 遺留的數據庫
- 提供初始數據
- 優化數據庫訪問
- 視圖層
- 基礎
- URL配置
- 視圖函數
- 快捷函數
- 裝飾器
- 參考
- 內建的視圖
- TemplateResponse 對象
- 文件上傳
- 概覽
- File 對象
- 儲存API
- 管理文件
- 自定義存儲
- 基于類的視圖
- 概覽
- 內建顯示視圖
- 內建編輯視圖
- API參考
- 分類索引
- 高級
- 生成 CSV
- 生成 PDF
- 中間件
- 概覽
- 內建的中間件類
- 模板層
- 基礎
- 面向設計師
- 語言概覽
- 人性化
- 面向程序員
- 表單
- 基礎
- 概覽
- 表單API
- 內建的Widget
- 高級
- 整合媒體
- 開發過程
- 設置
- 概覽
- 應用程序
- 異常
- 概覽
- django-admin 和 manage.py
- 添加自定義的命令
- 測試
- 介紹
- 部署
- 概述
- WSGI服務器
- 部署靜態文件
- 通過email追蹤代碼錯誤
- Admin
- 管理操作
- 管理文檔生成器
- 安全
- 安全概述
- 說明Django中的安全問題
- 點擊劫持保護
- 加密簽名
- 國際化和本地化
- 概述
- 本地化WEB UI格式化輸入
- “本地特色”
- 常見的網站應用工具
- 認證
- 概覽
- 使用認證系統
- 密碼管理
- 日志
- 分頁
- 會話
- 數據驗證
- 其它核心功能
- 按需內容處理
- 重定向
- 信號
- 系統檢查框架