django 1.8 官方文檔翻譯:13-1-2 使用Django認證系統

使用Django認證系統

這篇文檔解釋默認配置下Django認證系統的使用。這些配置已經逐步能夠知足大部分常見項目對的須要,能夠處理範圍很是普遍的任務,且具備一套細緻的密碼和權限實現。對於須要與默認配置不一樣需求的項目,Django支持_擴展和自定義_認證。html

Django的認證同時提供認證和受權,並一般統一稱爲認證系統,由於這些功能某些地方是耦合的。python

User對象

User對象是認證系統的核心。它們一般表示與你的站點進行交互的用戶,並用於啓用限制訪問、註冊用戶信息和關聯內容給建立者等。在Django的認證框架中只存在一種類型的用戶,所以諸如'superusers'或管理員'staff'用戶只是具備特殊屬性集的user對象,而不是不一樣類型的user對象。數據庫

默認user的基本屬性有:django

完整的參考請參閱full API documentation,該文檔更偏重特定的任務。app

建立users

建立users最直接的方法是使用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_.

建立superusers

使用createsuperuser命令建立superusers:

$ python manage.py createsuperuser --username=joe --email=joe@example.com

將會提示你輸入一個密碼。在你輸入一個密碼後,該user將會當即建立。若是不帶--username--email選項,將會提示你輸入這些值。

修改密碼

Django不會在user模型上存儲原始的(明文)密碼,而只是一個哈希(完整的細節參見_文檔:密碼是如何管理的_)。由於這個緣由,不要嘗試直接操做user的password屬性。這也是爲何建立一個user時要使用輔助函數。

若要修改一個用戶的密碼,你有幾種選擇:

manage.py changepassword *username*提供一種從命令行修改User密碼的方法。它提示你修改一個給定user的密碼,你必須輸入兩次。若是它們匹配,新的密碼將會當即修改。若是你沒有提供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頁面_修改user的密碼。

Django還提供_views__forms_用於容許user修改他們本身密碼。

New in Django 1.7\.

若是啓用了SessionAuthenticationMiddleware,修改user的密碼將會登出他們全部的會話。 詳細信息請參閱_密碼修改後會話失效_

認證Users

authenticate(_**credentials_)[source]

認證一個給定用戶名和密碼,請使用authenticate()。它以關鍵字參數形式接收憑證,對於默認的配置它是usernamepassword,若是密碼對於給定的用戶名有效它將返回一個User對象。若是密碼無效,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使用。除非你正在編寫你本身的認證系統,你可能不會使用到它。固然若是你在尋找一種登陸user的方法,請參見login_required()裝飾器。

權限和受權

Django從開始就帶有一個簡單的權限系統。它提供一種分配權限給特定的用戶和用戶組的方法。

它被Django的admin站點使用,但歡迎你在你本身的代碼中使用。

Django admin 站點使用以下的權限:

  • 查看"add"表單並添加一個只限具備該類型對象的「add」權限的用戶對象。

  • 查看修改列表、查看「change」表單以及修改一個只限具備該類型對象的「change」權限的用戶對象。

  • 刪除一個只限具備該類型對象的「delete」權限的用戶對象。

權限不但能夠根據每一個對象的類型,並且能夠根據特定的對象實例設置。經過使用ModelAdmin類提供的has_add_permission()has_change_permission()has_delete_permission()方法,能夠針對相同類型的不一樣對象實例自定義權限。

User對象具備兩個多對多的字段:groupsuser_permissionsUser對象能夠用和其它_Django 模型_同樣的方式訪問它們相關的對象:

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設置中列出時,它將確保爲你安裝的應用中的每一個Django模型建立3個默認的權限 – add、change和delete。

這些權限將在你運行manage.py migrate時建立;在添加django.contrib.authINSTALLED_APPS中以後,當你第一次運行migrate時,將會爲以前安裝的模型建立默認的權限,包括與其同時正在安裝的新的模型。以後,每當你運行manage.py migrate時,它都將爲新的模型建立默認的權限。

假設你有個應用的app_labelfoo和一個名爲Bar的模型,要測試基本的權限,你應該使用:

  • add: user.has_perm('foo.add_bar')

  • change: user.has_perm('foo.change_bar')

  • delete: user.has_perm('foo.delete_bar')

不多直接訪問Permission模型。

django.contrib.auth.models.Group模型是用戶分類的一種通用的方式,經過這種方式你能夠應用權限或其它標籤到這些用戶。一個用戶能夠屬於任意多個組。

組中某個用戶自動具備賦給那個組的權限。例如,若是組Site editors具備權限 can_edit_home_page,那麼該組中的任何用戶都具備該權限。

出權限以外,組仍是給用戶分類的一種方便的方法以給他們某些標籤或擴展的功能。例如,你能夠建立一個組'Special users',而後你能夠這樣寫代碼,給他們訪問你的站點僅限會員的部分,或者給他們發僅限於會員的郵件。

用程序建立權限

雖然_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,或者經過permissions屬性分配給Group

權限的緩存

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使用_會話_和中間件來攔截request 對象到認證系統中。

它們在每一個請求上提供一個request.user屬性,表示當前的用戶。若是當前的用戶沒有登入,該屬性將設置成AnonymousUser的一個實例,不然它將是User的實例。

你能夠經過is_authenticated()區分它們,像這樣:

if request.user.is_authenticated():
    # Do something for authenticated users.
    ...
else:
    # Do something for anonymous users.
    ...

如何登入一個用戶

若是你有一個認證了的用戶,你想把它附帶到當前的會話中 - 這能夠經過login()函數完成。

login()[source]

從視圖中登入一個用戶,請使用login()。它接受一個HttpRequest對象和一個User對象。login()使用Django的會話框架保存用戶的ID在會話中。

注意任何在匿名會話中設置的數據都會在用戶登入後的會話中都會記住。

這個例子展現你可能如何使用authenticate()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()以前經過authenticate()成功地認證該用戶。authenticate()User上設置一個屬性標識哪一種認證後臺成功認證了該用戶(細節參見_後臺的文檔_),且該信息在後面登陸的過程當中是須要的。若是你視圖登入一個直接從數據庫中取出的用戶,將會拋出一個錯誤。

如何登出一個用戶

logout()[source]

若要登出一個已經經過django.contrib.auth.login()登入的用戶,能夠在你的視圖中使用django.contrib.auth.logout()。 它接收一個HttpRequest對象且沒有返回值。例如:

from django.contrib.auth import logout

def logout_view(request):
    logout(request)
    # Redirect to a success page.

注意,即便用戶沒有登入logout()也不會拋出任何錯誤。

當你調用logout()時,當前請求的會話數據將被徹底清除。全部存在的數據都將清除。這是爲了防止另一我的使用相同的Web瀏覽器登入並訪問前一個用戶的會話數據。若是你想在用戶登出以後>能夠當即訪問放入會話中的數據,請在調用django.contrib.auth.logout()_以後_放入。

限制訪問給登錄後的用戶

原始的方法

限制頁面訪問的簡單、原始的方法是檢查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('%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]

做爲一個快捷方式,你可使用便捷的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/

  • 若是用戶已經登入,則正常執行視圖。視圖的代碼能夠安全地假設用戶已經登入。

默認狀況下,在成功認證後用戶應該被重定向的路徑存儲在查詢字符串的一個叫作)帶有一個可選的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而且你的登陸視圖正確關聯。例如,使用默認值,能夠添加下面幾行到你的URLconf中:

from django.contrib.auth import views as auth_views

url(r'^accounts/login/$', auth_views.login),

settings.LOGIN_URL同時還接收視圖函數名和_命名的URL模式_。這容許你自由地從新映射你的URLconf中的登陸視圖而不用更新設置。

login_required裝飾器不檢查user的is_active標誌位。

給已驗證登陸的用戶添加訪問限制

基於特定的權限和其餘方式來限制訪問,你最好按照前面所敘述的那樣操作。

簡單的方法就是在視圖中直接運行你對request.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]

你能夠用方便的 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

讓你指定那些沒有經過檢查的用戶要重定向至哪裏。若不指定其值,它多是默認的 settings.LOGIN_URL

redirect_field_name

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]

檢查一個用戶是否有指定的權限是相對常見的需求。所以,Django 提供了一個快捷方式: permission_required() 裝飾器:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote')
def my_view(request):
    ...

has_perm() 方法, 權限名稱採用以下方法 "<app label>.<permission codename>" (例如 polls.can_vote 表示在 polls 應用下一個模塊的權限。

要注意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() 裝飾器中, login_url默認爲settings.LOGIN_URL。

若是提供了 raise_exception 參數,裝飾器拋出PermissionDenied異常,使用 _the 403 (HTTP Forbidden) 視圖_而不是重定向到登陸頁面。

Changed in Django 1.7:

permission_required()裝飾器既能夠接收一個權限序列也能夠接收一個單個的權限。

對普通的視圖使用權限

若要對一個_基於類的普通視圖_使用權限,能夠在該類上裝飾View.dispatch方法。詳細細節參見_Decorating the class_。 另一個方法是_編寫一個封裝as_view()的mixin_

密碼更改後的會話失效

New in Django 1.7\.

警告

這種保護只在MIDDLEWARE_CLASSESSessionAuthenticationMiddleware開啓的狀況下應用。若是settings.py由Django ≥ 1.7\. 的startproject生成,它會被包含進來。

在Django 2.0中,會話驗證會變成強制性的, 不管是否開啓了SessionAuthenticationMiddleware 。 若是你擁有一個1.7以前的項目,或者使用不包含SessionAuthenticationMiddleware的模板生成的項目,考慮在閱讀下面的升級說明以後開啓它。

若是你的AUTH_USER_MODEL繼承自AbstractBaseUser,或者實現了它本身的get_session_auth_hash()方法,驗證後的會話會包含這個函數返回的哈希值。在AbstractBaseUser的狀況中,這是密碼字段的HMAC。若是開啓了SessionAuthenticationMiddleware ,Django會驗證每一個請求帶有的哈希值是否匹配服務端計算出來的哈希值。這容許用戶經過修改密碼來登出全部的會話。

Django中包含的默認的密碼修改視圖,以及django.contrib.auth中的 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開始運行你的站點,任何沒有登陸而且會話使用驗證哈希值升級過的用戶的現有會話都會失效,而且須要從新登陸。

注意

雖然get_session_auth_hash()給予SECRET_KEY,使用新的私鑰升級你的站點會使全部現有會話失效。

認證的視圖

Django提供一些視圖,你能夠用來處理登陸、登出和密碼管理。它們使用_stock auth 表單_,但你也能夠傳遞你本身的表單。

Django沒有爲認證視圖提供默認的模板。你應該爲你想要使用的視圖建立本身的模板。模板的上下文定義在每一個視圖中,參見_全部的認證視圖_.

使用視圖

有幾種不一樣的方法在你的項目中使用這些視圖。最簡單的方法是包含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文檔_

若是你想更多地控制你的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 實例,這容許你在渲染以前很容易自定義響應。實現它的一種方法是在你本身的視圖中包裝一個視圖:

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文檔_

全部的認證視圖

下面列出了django.contrib.auth提供的全部視圖。實現細節參見_使用視圖_

login(_request_, _template_name_, _redirect_field_name_, _authentication_form_, _current_app_, _extra_context_])[[source]

URL 名稱:login

關於使用命名URL模式的細節參見_URL 文檔_

可選的參數:

  • template_name: 用於用戶登陸視圖的模板名。默認爲registration/login.html

  • redirect_field_name: GET字段的名稱,包含登錄後重定向URL。默認爲next

  • authentication_form: 用於認證的可調用對象(一般只是一個表單類)。默認爲AuthenticationForm

  • current_app: 指示包含當前視圖的是哪一個應用。更多信息參見命名URL的解析策略

  • extra_context: 一個上下文數據的字典,將被添加到傳遞給模板的默認上下文數據中。

下面是django.contrib.auth.views.login所作的事情:

  • 若是經過 GET調用,它顯示一個POST給相同URL的登陸表單。後面有更多這方面的信息。

  • 若是經過POST調用並帶有用戶提交的憑證,它會嘗試登入該用戶。若是登入成功,該視圖重定向到next中指定的URL。若是next沒有提供,它重定向到settings.LOGIN_REDIRECT_URL(默認爲/accounts/profile/)。若是登入不成功,則從新顯示登陸表單。

你須要提供html模板給login,默認調用registration/login.html。模板會獲得4個模板上下文變量:

  • form: 一個表示AuthenticationFormForm對象。

  • next: 登入成功以後重定向的URL。它還可能包含一個查詢字符串。

  • site: 若是你沒有安裝site框架,這將被設置成RequestSite的一個實例,它從當前的HttpRequest得到site名稱和域名。

  • site_name: site.name的別名。若是你沒有安裝site框架,這將被設置成request.META['SERVER_NAME']的值。關於site 的更多信息,參見_「sites」 框架_

若是你不喜歡調用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_),你能夠經過authentication_form參數傳遞一個自定義的認證表單給登陸視圖。該表單必須在它的__init__方法中接收一個request關鍵字參數,並提供一個get_user方法,此方法返回認證過的用戶對象(這個方法永遠只在表單驗證成功後調用)。

logout(_request_, _next_page_, _template_name_, _redirect_field_name_, _current_app_, _extra_context_])[[source]

登出一個用戶。

URL名稱:logout

可選的參數:

  • next_page: 登出以後要重定向的URL。

  • template_name: 用戶登出以後,要展現的模板的完整名稱。若是不提供任何參數,默認爲registration/logged_out.html

  • redirect_field_name: 包含登出以後所重定向的URL的GET字段的名稱。默認爲 next。若是提供了GET參數,會覆蓋next_page URL。

  • current_app: 一個提示,代表哪一個應用含有了當前視圖。 詳見 命名空間下的URL解析策略

  • extra_context: 一個上下文數據的字典,會被添加到向模板傳遞的默認的上下文數據中。

模板上下文:

  • title: 本地化的字符串「登出」。

  • site: 根據SITE_ID 設置的當前站點。若是你並無安裝站點框架,會設置爲 RequestSite的示例,它從當前HttpRequest來獲取站點名稱和域名。

  • site_name: site.name的別名。若是沒有安裝站點框架,會設置爲request.META['SERVER_NAME']。站點的更多信息請見_「站點」框架_

  • current_app: 一個提示,代表哪一個應用含有了當前視圖。 詳見 命名空間下的URL解析策略

  • extra_context: 一個上下文數據的字典,會被添加到向模板傳遞的默認的上下文數據中。

logout_then_login(_request_, _login_url_, _current_app_, _extra_context_])[[source]

登出一個用戶,而後重定向到登陸頁面。

URL 名稱: 沒有提供默認的URL

可選的參數:

  • login_url: 登陸頁面要重定向的URL。若是沒有提供,默認爲settings.LOGIN_URL

  • current_app: 一個提示,代表哪一個應用含有了當前視圖。詳見 命名空間下的URL解析策略

  • extra_context: 一個上下文數據的字典,會被添加到向模板傳遞的默認的上下文數據中。

password_change(_request_, _template_name_, _post_change_redirect_, _password_change_form_, _current_app_, _extra_context_])[[source]

容許一個用戶修改他的密碼。

URL 名稱:password_change

可選的參數:

  • template_name: 用來顯示修改密碼錶單的template的全名。若是沒有提供,默認爲registration/password_change_form.html

  • post_change_redirect: 密碼修改爲功後重定向的URL。

  • password_change_form: 一個自定義的「修改密碼」表單,必須接受user 關鍵詞參數。表單用於實際修改用戶密碼。默認爲 PasswordChangeForm

  • current_app: 一個提示,暗示哪一個應用包含當前的視圖。詳見 命名空間下的URL解析策略

  • extra_context: 上下文數據的字典,會添加到傳遞給模板的默認的上下文數據中。

模板上下文:

  • form: 密碼修改表單(請見上面的password_change_form)。

password_change_done(_request_, _template_name_, _current_app_, _extra_context_])[[source]

這個頁面在用戶修改密碼以後顯示。

URL 名稱:password_change_done

可選參數:

  • template_name: 所使用模板的完整名稱。若是沒有提供,默認爲registration/password_change_done.html

  • current_app: 一個提示,暗示哪一個應用包含當前的視圖。 詳見 命名空間下的URL解析策略

  • 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]

容許用戶經過生成一次性的鏈接併發送到用戶註冊的郵箱地址中來重置密碼。

若是提供的郵箱地址不在系統中存在,這個視圖不會發送任何郵件,可是用戶也不會收到任何錯誤信息。這會阻止數據泄露給潛在的攻擊者。若是你打算在這種狀況提供錯誤信息,你能夠繼承PasswordResetForm,並使用password_reset_form 參數。

用無效密碼標記的用戶(參見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,

    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]

這個頁面在向用戶發送重置密碼的郵件後展現。若是password_reset()視圖沒有顯式設置 post_reset_redirectURL,默認會調用這個視圖。

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]

爲輸入新密碼展現表單。

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]

展現一個視圖,它通知用戶密碼修改爲功。

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]

重定向到登陸頁面,而後在登入成功後回到另外一個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

內建的驗證表單對他們處理的用戶模型作了特定假設。若是你使用了_自定義的用戶模型_,可能須要爲驗證系統定義你本身的表單。更多信息請見 _使用帶有自定義用戶模型的內建驗證表單_的文檔。

_class _AdminPasswordChangeForm[source]

管理界面中使用的表單,用於修改用戶密碼。

接受user做爲第一個參數。

_class _AuthenticationForm[source]

用於用戶登陸的表單。

接受request 做爲第一個參數,它儲存在表單實例中,被子類使用。

confirm_login_allowed(_user_)[source]

New in Django 1.7\.

一般, AuthenticationForm會拒絕 is_active標誌是False的用戶。你可使用自定義政策覆蓋這一行爲,來決定哪些用戶能夠登陸。使用一個繼承 AuthenticationForm並覆寫confirm_login_allowed方法的自定義表單來實現它。若是提供的用戶不能登陸,這個方法應該拋出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]

一個表單,容許用戶修改他們的密碼。

_class _PasswordResetForm[source]

一個表單,用於生成和經過郵件發送一次性密碼重置連接。

send_email(_subject_template_name_, _email_template_name_, _context_, _from_email_, _to_email_[, _html_email_template_name=None_])

New in Django 1.8\.

使用參數來發送EmailMultiAlternatives。能夠覆蓋來自定義郵件如何發送給用戶。

<colgroup><col class="field-name"><col class="field-body"></colgroup>
Parameters: * 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.

一般, save() 位於context中,並帶有 password_reset() 向它的email上下文傳遞的一些變量。

_class _SetPasswordForm[source]

容許用戶不輸入舊密碼修改密碼的表單。

_class _UserChangeForm[source]

用戶管理界面中修改用戶信息和許可的表單。

_class _UserCreationForm[source]

用於建立新用戶的表單。

模板中的認證數據

當你使用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實例的封裝,他是一個對於模板友好的權限代理。

{{ perms }} 對象中,單一屬性的查找是 User.has_module_perms的代理。若是已登陸的用戶在foo 應用中擁有任何許可,這個例子會顯示 True

{{ perms.foo }}

二級屬性的查找是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.admindjango.contrib.auth這兩個你都安裝了,將能夠經過admin方便地查看和管理用戶、組和權限。能夠像其它任何Django模型同樣建立和刪除用戶。能夠建立組,並分配權限給用戶和組。admin中還會保存和顯示對用戶模型編輯的日誌。

建立用戶

在admin的主頁,你應該能夠在「Auth」部分看到「Users」連接。「Add user」 頁面與標準admin頁面不一樣點在於它要求你在編輯用戶的其它字段以前先選擇一個用戶名和密碼。

另請注意:若是你想使得一個用戶可以使用Django的admin站點建立其它用戶, 你須要給他添加用戶_和_修改用戶的權限(例如,"Add user」 和「Change user」 權限)。若是一個帳號具備添加用戶的權限可是沒有權限修改他們,該帳號將不能添加用戶。爲何呢?由於若是你具備添加用戶的權限,你將能夠添加超級用戶,這些超級用戶將能夠修改其餘用戶。因此Django同時要求添加權限_和_修改權限做爲一種輕量的安全措施。

仔細考慮一下你是如何容許用戶管理權限的。若是你了一個非超級用戶編輯用戶的能力,這和給他們超級用戶的權限在最終效果上是同樣的,由於他們將可以提高他們本身下面的用戶的權限。

修改密碼

用戶密碼不會顯示在admin上(也不會存儲在數據庫中),可是會顯示 _密碼存儲的細節_。 這個信息的顯示中包含一條指向修改密碼錶單的連接,容許管理員修改用戶的密碼。

譯者:Django 文檔協做翻譯小組,原文:Using the authentication system

本文以 CC BY-NC-SA 3.0 協議發佈,轉載請保留做者署名和文章出處。

Django 文檔協做翻譯小組人手緊缺,有興趣的朋友能夠加入咱們,徹底公益性質。交流羣:467338606。

相關文章
相關標籤/搜索