使用 Django 身份驗證系統¶
本文說明 Django 身份驗證系統在其預設配置中的用法。此配置已演變為滿足最常見的專案需求,處理相當廣泛的任務,並仔細實作密碼和權限。對於身份驗證需求與預設值不同的專案,Django 支援廣泛的擴充和自訂身份驗證。
Django 身份驗證同時提供身份驗證和授權,通常稱為身份驗證系統,因為這些功能在某種程度上是耦合的。
User
物件¶
User
物件是身份驗證系統的核心。它們通常代表與您的網站互動的人員,並用於啟用諸如限制存取、註冊使用者設定檔、將內容與建立者關聯等功能。在 Django 的身份驗證框架中,只有一種使用者類別存在,即 '超級使用者'
或管理員 '員工'
使用者只是設定了特殊屬性的使用者物件,而不是不同的使用者物件類別。
預設使用者的主要屬性為
請參閱完整 API 文件
以取得完整參考,以下文件更偏向任務導向。
建立使用者¶
建立使用者最直接的方式是使用內含的 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 管理介面,也可以互動式建立使用者。
建立超級使用者¶
使用 createsuperuser
命令建立超級使用者
$ python manage.py createsuperuser --username=joe --email=joe@example.com
...\> py manage.py createsuperuser --username=joe --email=joe@example.com
系統會提示您輸入密碼。輸入密碼後,使用者會立即建立。如果您省略 --username
或 --email
選項,系統會提示您輸入這些值。
變更密碼¶
Django 不會將原始 (明文) 密碼儲存在使用者模型上,只會儲存雜湊值 (請參閱密碼管理方式的文件以取得完整詳細資料)。因此,請勿嘗試直接操作使用者的密碼屬性。這就是為什麼在建立使用者時使用輔助函式的原因。
若要變更使用者的密碼,您有幾個選項
manage.py changepassword *username*
提供從命令列變更使用者密碼的方法。它會提示您變更給定使用者的密碼,您必須輸入兩次。如果兩者相符,則會立即變更新密碼。如果您未提供使用者,則命令會嘗試變更使用者名稱與目前系統使用者相符的密碼。
您也可以使用 set_password()
以程式方式變更密碼
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username="john")
>>> u.set_password("new password")
>>> u.save()
如果您已安裝 Django 管理介面,也可以在身份驗證系統的管理頁面上變更使用者的密碼。
Django 也提供 檢視 和 表單,可用於允許使用者變更自己的密碼。
變更使用者的密碼將會登出他們的所有工作階段。請參閱密碼變更時的工作階段失效以取得詳細資料。
驗證使用者身份¶
- aauthenticate(request=None, **credentials)¶
非同步版本:
aauthenticate()
使用
authenticate()
來驗證一組憑證。它將憑證作為關鍵字引數,預設情況下為username
和password
,針對每個身份驗證後端檢查它們,如果憑證對後端有效,則傳回User
物件。如果憑證對任何後端無效,或後端引發PermissionDenied
,則傳回None
。例如from django.contrib.auth import authenticate user = authenticate(username="john", password="secret") if user is not None: # A backend authenticated the credentials ... else: # No backend authenticated the credentials ...
request
是可選的HttpRequest
,其會傳遞給身份驗證後端的authenticate()
方法。注意
這是驗證一組憑證的低階方式;例如,它是由
RemoteUserMiddleware
使用的。除非您正在撰寫自己的身份驗證系統,否則您可能不會使用此功能。相反地,如果您正在尋找登入使用者的方式,請使用LoginView
。在 Django 5.0 中變更新增了
aauthenticate()
函式。
Web 請求中的驗證¶
Django 使用 session 和中介軟體將驗證系統掛接到 request 物件
。
這些在每個請求中提供一個 request.user
屬性和一個 request.auser
異步方法,表示目前使用者。如果目前使用者尚未登入,則此屬性將設定為 AnonymousUser
的實例,否則它將是 User
的實例。
您可以使用 is_authenticated
來區分它們,如下所示
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
或在異步檢視中
user = await request.auser()
if user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
新增了 HttpRequest.auser()
方法。
如何登入使用者¶
如果您有一個想要附加到目前 Session 的已驗證使用者,則可以使用 login()
函數來完成。
- alogin(request, user, backend=None)¶
異步版本:
alogin()
要從檢視中登入使用者,請使用
login()
。它接受一個HttpRequest
物件和一個User
物件。login()
使用 Django 的 Session 架構,將使用者的 ID 儲存在 Session 中。請注意,在使用者登入後,匿名 Session 期間設定的任何資料都會保留在 Session 中。
此範例顯示您可能會如何同時使用
authenticate()
和login()
from django.contrib.auth import authenticate, login def my_view(request): username = request.POST["username"] password = request.POST["password"] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # Redirect to a success page. ... else: # Return an 'invalid login' error message. ...
在 Django 5.0 中變更新增了
alogin()
函數。
選擇驗證後端¶
當使用者登入時,使用者的 ID 和用於驗證的後端會儲存在使用者的 session 中。這允許在未來的請求中使用相同的 驗證後端 來取得使用者的詳細資料。要儲存在 session 中的驗證後端會依以下方式選擇:
如果提供了可選的
backend
參數,則使用該參數的值。如果存在
user.backend
屬性,則使用該屬性的值。這允許配對authenticate()
和login()
:authenticate()
會在其返回的使用者物件上設定user.backend
屬性。如果
AUTHENTICATION_BACKENDS
中只有一個backend
,則使用該backend
。否則,拋出一個例外。
在情況 1 和 2 中,backend
參數或 user.backend
屬性的值應為點分隔的導入路徑字串(如在 AUTHENTICATION_BACKENDS
中找到的),而不是實際的後端類別。
如何登出使用者¶
- alogout(request)¶
非同步版本:
alogout()
要登出透過
django.contrib.auth.login()
登入的使用者,請在您的 view 中使用django.contrib.auth.logout()
。它接收一個HttpRequest
物件,並且沒有回傳值。範例:from django.contrib.auth import logout def logout_view(request): logout(request) # Redirect to a success page.
請注意,如果使用者未登入,
logout()
不會拋出任何錯誤。當您呼叫
logout()
時,目前請求的 session 資料會被完全清除。所有現有的資料都會被移除。這是為了防止其他人使用相同的網路瀏覽器登入並存取先前使用者的 session 資料。如果您想在登出後立即讓使用者可以使用任何 session 中的資料,請在呼叫django.contrib.auth.logout()
之後 執行。在 Django 5.0 中變更已新增
alogout()
函式。
限制對已登入使用者的存取¶
原始方法¶
限制對頁面存取的原始方法是檢查 request.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(f"{settings.LOGIN_URL}?next={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='next', login_url=None)[原始碼]¶
作為一個捷徑,您可以使用方便的
login_required()
修飾器from django.contrib.auth.decorators import login_required @login_required def my_view(request): ...
login_required()
執行以下操作如果使用者未登入,則重新導向到
settings.LOGIN_URL
,並在查詢字串中傳遞目前的絕對路徑。例如:/accounts/login/?next=/polls/3/
。如果使用者已登入,則正常執行 view。view 程式碼可以自由假設使用者已登入。
預設情況下,使用者在成功驗證後應重新導向的路徑儲存在名為
"next"
的查詢字串參數中。如果您希望對此參數使用不同的名稱,login_required()
接收一個可選的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()
也接收一個可選的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
和您的登入 view 已正確關聯。例如,使用預設值,將以下程式碼加入您的 URLconf:from django.contrib.auth import views as auth_views path("accounts/login/", auth_views.LoginView.as_view()),
settings.LOGIN_URL
也接受 view 函式名稱和 具名 URL 模式。這允許您在 URLconf 中自由地重新對應您的登入 view,而無需更新設定。
注意
login_required
修飾器不會檢查使用者的 is_active
旗標,但預設的 AUTHENTICATION_BACKENDS
會拒絕不活躍的使用者。
另請參閱
如果您正在為 Django 的管理介面編寫自訂 view(或需要與內建 view 使用相同的授權檢查),您可能會發現 django.contrib.admin.views.decorators.staff_member_required()
修飾器是 login_required()
的一個有用的替代方案。
已新增對包裝非同步 view 函式的支援。
LoginRequiredMixin
混合類別¶
當使用 基於類別的 view 時,您可以使用 LoginRequiredMixin
來實現與 login_required
相同的行為。這個混合類別應位於繼承列表的最左側位置。
- class LoginRequiredMixin[原始碼]¶
如果 view 使用這個混合類別,所有未經身份驗證的使用者的請求將會被重新導向到登入頁面,或顯示 HTTP 403 禁止錯誤,具體取決於
raise_exception
參數。您可以設定
AccessMixin
的任何參數來自訂未授權使用者的處理方式from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): login_url = "/login/" redirect_field_name = "redirect_to"
注意
如同 login_required
修飾器一樣,這個混合類別不會檢查使用者的 is_active
旗標,但預設的 AUTHENTICATION_BACKENDS
會拒絕不活躍的使用者。
login_not_required
修飾器¶
當安裝 LoginRequiredMiddleware
時,預設情況下所有 view 都需要驗證。某些 view,例如登入 view,可能需要停用此行為。
- login_not_required()[原始碼]¶
當安裝
LoginRequiredMiddleware
時,允許對此 view 發出未經驗證的請求。
限制對通過測試的已登入使用者的存取¶
要根據某些權限或其他測試來限制存取,您基本上會執行與前一節所述相同的操作。
您可以直接在 view 中對 request.user
執行您的測試。例如,此 view 會檢查使用者是否在所需的網域中擁有電子郵件,如果沒有,則重新導向到登入頁面
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(test_func, login_url=None, redirect_field_name='next')[原始碼]¶
作為一個快捷方式,您可以使用方便的
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()
接受一個必要參數:一個可呼叫物件,該物件接受一個User
物件,如果允許使用者檢視頁面,則返回True
。請注意,user_passes_test()
不會自動檢查User
是否為匿名使用者。user_passes_test()
接受兩個可選參數login_url
允許您指定未通過測試的使用者將被重新導向到的 URL。它可能是登入頁面,如果沒有指定,則預設為
settings.LOGIN_URL
。redirect_field_name
與
login_required()
相同。將其設定為None
會將其從 URL 中移除,如果您要將未通過測試的使用者重新導向到沒有「下一頁」的非登入頁面,您可能會想要這樣做。
例如
@user_passes_test(email_check, login_url="/login/") def my_view(request): ...
在 Django 5.1 中變更新增了對包裝非同步視圖函式和使用非同步測試可呼叫物件的支援。
- class UserPassesTestMixin[原始碼]¶
當使用 基於類別的視圖 時,您可以使用
UserPassesTestMixin
來完成此操作。- test_func()[原始碼]¶
您必須覆寫類別的
test_func()
方法來提供執行的測試。此外,您可以設定AccessMixin
的任何參數來自訂未授權使用者的處理方式from django.contrib.auth.mixins import UserPassesTestMixin class MyView(UserPassesTestMixin, View): def test_func(self): return self.request.user.email.endswith("@example.com")
- get_test_func()[原始碼]¶
您也可以覆寫
get_test_func()
方法,讓 mixin 對其檢查使用不同的命名函式(而不是test_func()
)。
堆疊
UserPassesTestMixin
由於
UserPassesTestMixin
的實作方式,您無法在繼承清單中堆疊它們。以下操作無效class TestMixin1(UserPassesTestMixin): def test_func(self): return self.request.user.email.endswith("@example.com") class TestMixin2(UserPassesTestMixin): def test_func(self): return self.request.user.username.startswith("django") class MyView(TestMixin1, TestMixin2, View): ...
如果
TestMixin1
會呼叫super()
並將該結果納入考量,TestMixin1
將不再能獨立運作。
permission_required
裝飾器¶
- permission_required(perm, login_url=None, raise_exception=False)[原始碼]¶
檢查使用者是否具有特定權限是一項相對常見的工作。因此,Django 為此情況提供了一個快捷方式:
permission_required()
裝飾器from django.contrib.auth.decorators import permission_required @permission_required("polls.add_choice") def my_view(request): ...
就像
has_perm()
方法一樣,權限名稱採用"<應用程式標籤>.<權限程式碼名稱>"
的形式(例如,polls.add_choice
用於polls
應用程式中模型的權限)。該裝飾器也可以接受權限的可迭代物件,在這種情況下,使用者必須具有所有權限才能存取該視圖。
請注意,
permission_required()
也接受一個可選的login_url
參數from django.contrib.auth.decorators import permission_required @permission_required("polls.add_choice", login_url="/loginpage/") def my_view(request): ...
與
login_required()
裝飾器一樣,login_url
預設為settings.LOGIN_URL
。如果給定了
raise_exception
參數,裝飾器將引發PermissionDenied
,提示 403 (HTTP Forbidden) 視圖,而不是重新導向到登入頁面。如果您想使用
raise_exception
,但也想讓您的使用者有機會先登入,您可以新增login_required()
裝飾器from django.contrib.auth.decorators import login_required, permission_required @login_required @permission_required("polls.add_choice", raise_exception=True) def my_view(request): ...
這也可以避免在
LoginView
的redirect_authenticated_user=True
且已登入的使用者不具有所有必要權限時的重新導向迴圈。
已新增對包裝非同步 view 函式的支援。
PermissionRequiredMixin
mixin¶
要將權限檢查套用到 基於類別的視圖,您可以使用 PermissionRequiredMixin
- class PermissionRequiredMixin[原始碼]¶
這個 mixin,就像
permission_required
裝飾器一樣,檢查存取視圖的使用者是否具有所有給定的權限。您應使用permission_required
參數指定權限(或權限的可迭代物件)from django.contrib.auth.mixins import PermissionRequiredMixin class MyView(PermissionRequiredMixin, View): permission_required = "polls.add_choice" # Or multiple of permissions: permission_required = ["polls.view_choice", "polls.change_choice"]
您可以設定
AccessMixin
的任何參數來自訂未授權使用者的處理方式。您也可以覆寫這些方法
- has_permission()[原始碼]¶
返回一個布林值,表示目前使用者是否有權限執行裝飾的視圖。預設情況下,這會返回使用
get_permission_required()
返回的權限清單呼叫has_perms()
的結果。
驗證檢視¶
Django 提供數個檢視,您可以將其用於處理登入、登出和密碼管理。這些檢視使用 stock auth 表單,但您也可以傳入自己的表單。
Django 沒有為驗證檢視提供預設範本。您應該為要使用的檢視建立自己的範本。範本內容記錄在每個檢視中,請參閱所有驗證檢視。
使用檢視¶
在您的專案中實作這些檢視有不同的方法。最簡單的方法是在您自己的 URLconf 中包含 django.contrib.auth.urls
中提供的 URLconf,例如
urlpatterns = [
path("accounts/", include("django.contrib.auth.urls")),
]
這將包含以下 URL 模式
accounts/login/ [name='login']
accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']
這些檢視會提供 URL 名稱,方便您參考。有關使用具名 URL 模式的詳細資訊,請參閱URL 文件。
如果您想對 URL 擁有更多控制權,可以在您的 URLconf 中參考特定的檢視
from django.contrib.auth import views as auth_views
urlpatterns = [
path("change-password/", auth_views.PasswordChangeView.as_view()),
]
這些檢視具有可選參數,可用於變更檢視的行為。例如,如果您想要變更檢視使用的範本名稱,可以提供 template_name
參數。執行此操作的一種方法是在 URLconf 中提供關鍵字引數,這些引數會傳遞到檢視。例如
urlpatterns = [
path(
"change-password/",
auth_views.PasswordChangeView.as_view(template_name="change-password.html"),
),
]
所有檢視都是基於類別的,這讓您可以透過子類別輕鬆地自訂它們。
所有驗證檢視¶
這是 django.contrib.auth
提供的所有檢視的清單。有關實作詳細資訊,請參閱使用檢視。
- class LoginView[原始碼]¶
URL 名稱:
login
有關使用具名 URL 模式的詳細資訊,請參閱URL 文件。
方法和屬性
- template_name¶
用於顯示使用者登入畫面的樣板名稱。預設為
registration/login.html
。
- next_page¶
登入後要重新導向的 URL。預設為
LOGIN_REDIRECT_URL
。
- redirect_field_name¶
包含登入後要重新導向 URL 的
GET
欄位名稱。預設為next
。如果傳入指定的GET
參數,則會覆寫get_default_redirect_url()
URL。
- authentication_form¶
用於驗證的可呼叫物件(通常為表單類別)。預設為
AuthenticationForm
。
- extra_context¶
一個字典,包含要新增到傳遞給樣板的預設上下文資料的額外資料。
- redirect_authenticated_user¶
一個布林值,用於控制已驗證的使用者訪問登入頁面時,是否會像剛成功登入一樣被重新導向。預設為
False
。警告
如果您啟用
redirect_authenticated_user
,其他網站可以透過請求您網站上圖片檔案的重新導向 URL 來判斷其訪客是否在您的網站上通過驗證。為避免這種「社交媒體指紋」資訊洩漏,請將所有圖片和您的網站圖示託管在單獨的網域上。啟用
redirect_authenticated_user
也可能在使用permission_required()
裝飾器時導致重新導向迴圈,除非使用raise_exception
參數。
- success_url_allowed_hosts¶
除了
request.get_host()
之外,在登入後可以安全重新導向的主機的set
。預設為一個空的set
。
- get_default_redirect_url()[原始碼]¶
傳回登入後要重新導向的 URL。預設實作會解析並傳回
next_page
(如果已設定),否則傳回LOGIN_REDIRECT_URL
。
以下是
LoginView
的運作方式如果透過
GET
呼叫,它會顯示一個登入表單,該表單會透過 POST 到相同的 URL。稍後會詳細說明。如果透過
POST
呼叫並帶有使用者提交的憑證,它會嘗試讓使用者登入。如果登入成功,檢視會重新導向到next
中指定的 URL。如果未提供next
,則會重新導向到settings.LOGIN_REDIRECT_URL
(預設為/accounts/profile/
)。如果登入不成功,則會重新顯示登入表單。
您有責任為登入樣板提供 HTML,預設名稱為
registration/login.html
。此樣板會傳遞四個樣板上下文變數form
:代表AuthenticationForm
的Form
物件。next
:成功登入後要重新導向的 URL。這也可能包含查詢字串。site
:根據SITE_ID
設定的目前Site
。如果您沒有安裝網站框架,這會設定為RequestSite
的實例,後者會從目前的HttpRequest
衍生網站名稱和網域。site_name
:site.name
的別名。如果您沒有安裝網站框架,這將設定為request.META['SERVER_NAME']
的值。有關網站的更多資訊,請參閱「網站」框架。
如果您不想將樣板命名為
registration/login.html
,您可以透過 URLconf 中as_view
方法的額外參數傳遞template_name
參數。例如,此 URLconf 行會改用myapp/login.html
path("accounts/login/", auth_views.LoginView.as_view(template_name="myapp/login.html")),
您也可以使用
redirect_field_name
指定包含登入後要重新導向 URL 的GET
欄位名稱。預設情況下,該欄位名為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 %} {% if next %} {% if user.is_authenticated %} <p>Your account doesn't have access to this page. To proceed, please login with an account that has access.</p> {% else %} <p>Please login to see this page.</p> {% endif %} {% endif %} <form method="post" action="{% url '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> {# Assumes you set up the password_reset view in your URLconf #} <p><a href="{% url 'password_reset' %}">Lost password?</a></p> {% endblock %}
如果您已自訂驗證(請參閱 自訂驗證),您可以透過設定
authentication_form
屬性來使用自訂驗證表單。此表單必須在其__init__()
方法中接受request
關鍵字引數,並提供一個傳回已驗證使用者物件的get_user()
方法 (此方法僅在表單驗證成功後才會被呼叫)。
- class LogoutView[原始碼]¶
在
POST
請求時登出使用者。URL 名稱:
logout
屬性
- next_page¶
登出後要重新導向的 URL。預設為
LOGOUT_REDIRECT_URL
。
- template_name¶
登出使用者後要顯示的樣板完整名稱。預設為
registration/logged_out.html
。
- extra_context¶
一個字典,包含要新增到傳遞給樣板的預設上下文資料的額外資料。
- success_url_allowed_hosts¶
除了
request.get_host()
之外,允許在登出後重新導向的安全主機的set
。預設值為空的set
。
範本上下文
title
:本地化的字串「已登出」。site
:根據SITE_ID
設定的目前Site
。如果您沒有安裝網站框架,這會設定為RequestSite
的實例,後者會從目前的HttpRequest
衍生網站名稱和網域。site_name
:site.name
的別名。如果您沒有安裝網站框架,這將設定為request.META['SERVER_NAME']
的值。有關網站的更多資訊,請參閱「網站」框架。
- logout_then_login(request, login_url=None)[原始碼]¶
在
POST
請求上登出使用者,然後重新導向到登入頁面。URL 名稱: 未提供預設 URL
選用參數
login_url
:要重新導向到的登入頁面 URL。如果未提供,則預設為settings.LOGIN_URL
。
- class PasswordChangeView[原始碼]¶
URL 名稱:
password_change
允許使用者變更其密碼。
屬性
- template_name¶
用於顯示密碼變更表單的範本完整名稱。如果未提供,則預設為
registration/password_change_form.html
。
- success_url¶
成功變更密碼後要重新導向的 URL。預設值為
'password_change_done'
。
- form_class¶
自訂的「變更密碼」表單,必須接受
user
關鍵字引數。此表單負責實際變更使用者的密碼。預設值為PasswordChangeForm
。
- extra_context¶
一個字典,包含要新增到傳遞給樣板的預設上下文資料的額外資料。
範本上下文
form
:密碼變更表單(請參閱上面的form_class
)。
- class PasswordChangeDoneView[原始碼]¶
URL 名稱:
password_change_done
使用者變更密碼後顯示的頁面。
屬性
- template_name¶
要使用的範本完整名稱。如果未提供,則預設為
registration/password_change_done.html
。
- extra_context¶
一個字典,包含要新增到傳遞給樣板的預設上下文資料的額外資料。
- class PasswordResetView[原始碼]¶
URL 名稱:
password_reset
允許使用者透過產生一次性使用連結來重設其密碼,該連結可用於重設密碼,並將該連結傳送至使用者註冊的電子郵件地址。
如果滿足以下條件,此檢視將會傳送電子郵件
系統中存在提供的電子郵件地址。
要求的用戶處於活動狀態(
User.is_active
為True
)。要求的用戶擁有可用的密碼。標記為不可用密碼的使用者(請參閱
set_unusable_password()
)不允許要求重設密碼,以防止在使用 LDAP 等外部驗證來源時遭到濫用。
如果 不 滿足這些條件的任何一項,則不會傳送電子郵件,但使用者也不會收到任何錯誤訊息。這可以防止資訊洩漏給潛在的攻擊者。如果要在這種情況下提供錯誤訊息,您可以子類化
PasswordResetForm
並使用form_class
屬性。注意
請注意,傳送電子郵件會花費額外時間,因此您可能會因為現有電子郵件地址的重設請求持續時間與不存在電子郵件地址的重設請求持續時間之間的差異,而容易受到電子郵件地址列舉計時攻擊。為了減少開銷,您可以使用允許非同步傳送電子郵件的第三方套件,例如 django-mailer。
屬性
- template_name¶
用於顯示密碼重設表單的範本完整名稱。如果未提供,則預設為
registration/password_reset_form.html
。
- form_class¶
用於取得要重設密碼的使用者電子郵件的表單。預設值為
PasswordResetForm
。
- email_template_name¶
用於產生帶有重設密碼連結之電子郵件的範本完整名稱。如果未提供,則預設為
registration/password_reset_email.html
。
- subject_template_name¶
用於帶有重設密碼連結之電子郵件主旨的範本完整名稱。如果未提供,則預設為
registration/password_reset_subject.txt
。
- token_generator¶
用於檢查一次性連結的類別實例。這將預設為
default_token_generator
,它是django.contrib.auth.tokens.PasswordResetTokenGenerator
的實例。
- success_url¶
成功發出密碼重設請求後要重新導向的 URL。預設值為
'password_reset_done'
。
- from_email¶
有效的電子郵件地址。依預設,Django 會使用
DEFAULT_FROM_EMAIL
。
- extra_context¶
一個字典,包含要新增到傳遞給樣板的預設上下文資料的額外資料。
- html_email_template_name¶
用於產生帶有密碼重設連結之 text/html 多部分電子郵件的範本完整名稱。依預設,不會傳送 HTML 電子郵件。
- extra_email_context¶
電子郵件範本中可用的上下文資料字典。它可用於覆寫下列列出的預設範本上下文值,例如
domain
。
範本上下文
form
:用於重設使用者密碼的表單(請參閱上面的form_class
)。
電子郵件範本上下文
email
:user.email
的別名user
:目前的User
,根據email
表單欄位。只有活動使用者才能重設其密碼(User.is_active is True
)。site_name
:site.name
的別名。如果您沒有安裝網站框架,這將設定為request.META['SERVER_NAME']
的值。有關網站的更多資訊,請參閱「網站」框架。domain
:site.domain
的別名。如果未安裝網站架構,則此值將設定為request.get_host()
的值。protocol
:http 或 httpsuid
:使用者以 base 64 編碼的主索引鍵。token
:用於檢查重設連結是否有效的權杖。
範例
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 %}
主旨範本使用相同的範本上下文。主旨必須是單行純文字字串。
- class PasswordResetDoneView[原始碼]¶
URL 名稱:
password_reset_done
當使用者收到重設密碼連結的電子郵件後,會顯示此頁面。如果
PasswordResetView
沒有設定明確的success_url
URL,則預設會呼叫此檢視。注意
如果系統中不存在提供的電子郵件地址、使用者處於非啟用狀態,或擁有無法使用的密碼,使用者仍會被重新導向至此檢視,但不會寄送電子郵件。
屬性
- template_name¶
要使用的範本完整名稱。如果未提供,則預設為
registration/password_reset_done.html
。
- extra_context¶
一個字典,包含要新增到傳遞給樣板的預設上下文資料的額外資料。
- class PasswordResetConfirmView[原始碼]¶
URL 名稱:
password_reset_confirm
顯示輸入新密碼的表單。
來自 URL 的關鍵字引數
uidb64
:以 base 64 編碼的使用者 ID。token
:用來檢查密碼是否有效的權杖。
屬性
- template_name¶
用於顯示確認密碼檢視的範本完整名稱。預設值為
registration/password_reset_confirm.html
。
- token_generator¶
用於檢查密碼的類別實例。預設為
default_token_generator
,它是django.contrib.auth.tokens.PasswordResetTokenGenerator
的實例。
- post_reset_login¶
一個布林值,表示在密碼重設成功後是否應自動驗證使用者身分。預設為
False
。
- post_reset_login_backend¶
如果
post_reset_login
為True
,則在驗證使用者身分時要使用的驗證後端的虛線路徑。僅當您設定了多個AUTHENTICATION_BACKENDS
時才需要。預設為None
。
- form_class¶
將用於設定密碼的表單。預設為
SetPasswordForm
。
- success_url¶
密碼重設完成後要重新導向的 URL。預設為
'password_reset_complete'
。
- extra_context¶
一個字典,包含要新增到傳遞給樣板的預設上下文資料的額外資料。
- reset_url_token¶
顯示為密碼重設 URL 組件的權杖參數。預設為
'set-password'
。
範本上下文
form
:用於設定新使用者密碼的表單(請參閱上方的form_class
)。validlink
:布林值,如果連結(uidb64
和token
的組合)有效或尚未被使用,則為 True。
輔助函數¶
- redirect_to_login(next, login_url=None, redirect_field_name='next')[原始碼]¶
重新導向至登入頁面,然後在成功登入後回到另一個 URL。
必要引數
next
:成功登入後要重新導向到的 URL。
選用參數
login_url
:要重新導向到的登入頁面 URL。如果未提供,則預設為settings.LOGIN_URL
。redirect_field_name
:包含登入後要重新導向到的 URL 的GET
欄位名稱。如果傳遞了給定的GET
參數,則會覆寫next
。
內建表單¶
如果您不想使用內建的檢視,但又希望方便地不必為此功能撰寫表單,則驗證系統會提供數個位於 django.contrib.auth.forms
中的內建表單。
注意
內建的驗證表單對它們所使用的使用者模型做出某些假設。如果您正在使用自訂使用者模型,則可能需要為驗證系統定義自己的表單。如需詳細資訊,請參閱有關將內建驗證表單與自訂使用者模型一起使用的說明文件。
- class AdminPasswordChangeForm[原始碼]¶
管理介面中用於變更使用者密碼的表單,包括設定
無法使用的密碼
的功能,這會阻止使用者使用基於密碼的驗證方式登入。將
user
作為第一個位置引數。在 Django 5.1 中變更新增了停用(或重新啟用)基於密碼驗證的選項。
- class AdminUserCreationForm[原始碼]¶
- Django 5.1.1 中的新功能。
管理介面中用於建立新使用者的表單。繼承自
UserCreationForm
。它包含一個額外的
usable_password
欄位,預設為啟用。如果啟用usable_password
,它會驗證password1
和password2
是否為非空白且相符,使用validate_password()
驗證密碼,並使用set_password()
設定使用者的密碼。如果停用usable_password
,則不會進行密碼驗證,並透過呼叫set_unusable_password()
來停用使用者的基於密碼驗證方式。
- class AuthenticationForm[原始碼]¶
用於登入使用者的表單。
將
request
作為其第一個位置引數,並將其儲存在表單實例上供子類別使用。- confirm_login_allowed(user)[原始碼]¶
預設情況下,
AuthenticationForm
會拒絕is_active
標記設為False
的使用者。您可以使用自訂策略覆寫此行為,以決定哪些使用者可以登入。方法是使用自訂表單,該表單繼承AuthenticationForm
並覆寫confirm_login_allowed()
方法。如果給定的使用者無法登入,此方法應引發ValidationError
。例如,允許所有使用者登入,無論「active」狀態為何
from django.contrib.auth.forms import AuthenticationForm class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm): def confirm_login_allowed(self, user): pass
(在這種情況下,您還需要使用允許非使用中用戶的身份驗證後端,例如
AllowAllUsersModelBackend
。)或者只允許某些使用中的使用者登入
class PickyAuthenticationForm(AuthenticationForm): def confirm_login_allowed(self, user): if not user.is_active: raise ValidationError( _("This account is inactive."), code="inactive", ) if user.username.startswith("b"): raise ValidationError( _("Sorry, accounts starting with 'b' aren't welcome here."), code="no_b_users", )
- class BaseUserCreationForm[原始碼]¶
用於建立新使用者的
ModelForm
。如果您需要自訂使用者建立表單,這是建議的基礎類別。它有三個欄位:
username
(來自使用者模型)、password1
和password2
。它會驗證password1
和password2
是否匹配,使用validate_password()
驗證密碼,並使用set_password()
設定使用者的密碼。
- class PasswordResetForm[原始碼]¶
用於產生並透過電子郵件傳送一次性使用連結以重設使用者密碼的表單。
- send_mail(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)[原始碼]¶
使用引數傳送
EmailMultiAlternatives
。可以覆寫此方法以自訂電子郵件傳送給使用者的方式。如果您選擇覆寫此方法,請注意處理由於電子郵件傳送失敗而可能引發的例外情況。- 參數:
subject_template_name – 主旨的範本。
email_template_name – 電子郵件內文的範本。
context – 傳遞至
subject_template
、email_template
和html_email_template
的內容(如果它不是None
)。from_email – 寄件者的電子郵件。
to_email – 請求者的電子郵件。
html_email_template_name – HTML 內文的範本;預設為
None
,在這種情況下會傳送純文字電子郵件。
預設情況下,
save()
會使用PasswordResetView
傳遞給其電子郵件內容的相同變數來填入context
。
- class UserCreationForm[原始碼]¶
繼承自
BaseUserCreationForm
。為了避免與類似的使用者名稱混淆,此表單不允許僅大小寫不同的使用者名稱。
範本中的身份驗證資料¶
當您使用 RequestContext
時,目前登入的使用者及其權限會在 範本內容 中提供。
技術細節
嚴格來說,只有當您使用 RequestContext
且啟用 'django.contrib.auth.context_processors.auth'
內容處理器時,這些變數才會在範本內容中提供。它位於預設產生的設定檔中。如需更多資訊,請參閱 RequestContext 文件。
使用者¶
當呈現範本 RequestContext
時,目前登入的使用者(User
實例或 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.PermWrapper
的實例,它是權限的範本友善代理。
將 {{ perms }}
的單一屬性查閱評估為布林值,是 User.has_module_perms()
的代理。例如,檢查登入的使用者是否在 foo
應用程式中擁有任何權限
{% if perms.foo %}
將雙層屬性查閱評估為布林值,是 User.has_perm()
的代理。例如,檢查登入的使用者是否具有 foo.add_vote
權限
{% if perms.foo.add_vote %}
以下是在範本中檢查權限的更完整範例
{% if perms.foo %}
<p>You have permission to do something in the foo app.</p>
{% if perms.foo.add_vote %}
<p>You can vote!</p>
{% endif %}
{% if perms.foo.add_driving %}
<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.add_vote' in perms %}
<p>In lookup works, too.</p>
{% endif %}
{% endif %}
在管理介面中管理使用者¶
當您同時安裝 django.contrib.admin
和 django.contrib.auth
時,管理介面會提供方便的方式來檢視和管理使用者、群組和權限。可以像任何 Django 模型一樣建立和刪除使用者。可以建立群組,並且可以將權限指派給使用者或群組。也會儲存並顯示管理介面中使用者對模型所做的編輯記錄。
建立使用者¶
您應該會在主要管理索引頁面的「Auth」區段中看到「Users」的連結。「Add user」管理頁面與標準管理頁面不同,它要求您選擇使用者名稱和密碼,然後才能編輯使用者的其他欄位。或者,在此頁面上,您可以選擇使用者名稱並停用該使用者的基於密碼的身份驗證。
另請注意:如果您希望使用者帳戶能夠透過 Django 管理網站建立使用者,您需要給予他們新增使用者和變更使用者的權限(即「新增使用者」和「變更使用者」權限)。如果帳戶有新增使用者的權限但沒有變更使用者的權限,則該帳戶將無法新增使用者。為什麼?因為如果您有新增使用者的權限,您就有權建立超級使用者,而超級使用者反過來可以變更其他使用者。因此,Django 需要新增和變更權限作為一個輕微的安全措施。
請謹慎考慮您如何允許使用者管理權限。如果您給予非超級使用者編輯使用者的能力,這最終等同於給予他們超級使用者狀態,因為他們將能夠提升包括他們自己在內的使用者的權限!
變更密碼¶
使用者密碼不會顯示在管理介面中(也不會儲存在資料庫中),但會顯示 密碼儲存詳細資訊。此資訊的顯示中包含一個連結,連至密碼變更表單,該表單允許管理員變更或取消設定使用者密碼。