共用方式為


教學課程:在Visual Studio中使用 Django 驗證使用者

本文是教學系列中的第 5 步:在 Visual Studio 中使用 Django 網頁框架

驗證是 Web 應用程式的常見需求。 Visual Studio 中的 Django Web 專案 範本提供 Django 專案 settings.py 檔案中驗證所需的所有模組。 本教學課程系列中的步驟 4 會使用此範本建立 Django Web 應用程式。 在步驟 5 中,您會探索範本的驗證功能,並使用執行中應用程式中的功能。

在教學課程的步驟 5 中,您會瞭解如何:

  • 在 Visual Studio 的 Django Web 專案範本中探索驗證流程
  • 檢查支援驗證程式的程序代碼
  • 修改程式代碼以啟用 Django 系統管理員介面的存取權
  • 執行 Django Web 應用程式並使用驗證功能

先決條件

  • Visual Studio 解決方案和 Django Web 應用程式,以 Django Web 專案 範本為基礎(DjangoWeb)。 步驟 4:使用完整的 Django Web 專案範本 說明如何建立此應用程式。

  • Django Web 應用程式必須具有進階使用者(系統管理員)帳戶。 步驟 4 (建立 Django 進階使用者) 說明如何建立進階用戶認證。

  • 如需有關 Django 範本版本、Visual Studio 專案與 Django 專案,以及 Mac 上 Python 開發的詳細資訊,請檢閱本教學課程系列的步驟 1 中的 必要條件 一節。

探索驗證流程

本節說明 Django Web 應用程式 Django Web 專案 範本所提供的預設驗證流程。

  1. 在 Visual Studio 中,選取 [偵錯]>[開始偵錯]F5) 啟動 Django Web 應用程式 (DjangoWeb)。

  2. 當應用程式在瀏覽器中開啟時,請注意導覽列右側的 [登入] 選項:

    顯示執行 Django Web 應用程式中導覽列上 [登入] 選項的螢幕快照。

    執行中的 Django 應用程式具有三個頁面選項的導覽列,HomeAboutContact,以及 [登入] 選項。 驗證組態可讓任何使用者查看 「首頁」、「關於」和「聯繫人」頁面上的內容。

  3. 針對 Django Web 應用程式的已驗證存取權,指定的進階使用者可以使用 [登入] 選項,這會開啟 [登入] 頁面:

    顯示執行中 Django Web 應用程式中進階使用者的登入驗證頁面的螢幕快照。

  4. 進階使用者登入之後,他們可以存取網站的受限制頁面檢視,並完成系統管理工作:

    螢幕快照,其中顯示 Django 超級使用者可用的其中一個頁面檢視,以及具有 [註銷] 選項的更新導覽列。

  5. 超級使用者可以使用 [登出] 選項來登出 Django 網頁應用程式,並以未經驗證的使用者身分返回 Django 網頁應用程式的 [首頁]。

在下列各節中,您會修改驗證組態,以支援超級使用者的 Django 管理員網站存取。

檢查驗證碼

既然您已瞭解 Django Web 應用程式的一般驗證功能,您即可檢查 django Web Project 範本所提供的基礎程式代碼:

  1. 在 [方案總管]中,展開專案的 app/templates/app 資料夾。 下列步驟會檢閱此資料夾中的數個檔案。

  2. 開啟基底範本檔案,layout.html。 捲動至 <div class="navbar ...> 元素,並找出 {% include app/loginpartial.html %} 標籤。

    {% include %} 標籤標會指示 Django 的範本系統在包含範本中此時提取內含檔案的內容。

  3. 開啟 loginpartial.html 檔案。 觀察此範本如何使用條件式標記 {% if user.is_authenticated %} 以及 {% else %} 標記,根據使用者是否已驗證來轉譯不同的UI元素:

    {% if user.is_authenticated %}
    <form id="logoutForm" action="/logout" method="post" class="navbar-right">
        {% csrf_token %}
        <ul class="nav navbar-nav navbar-right">
            <li><span class="navbar-brand">Hello {{ user.username }}!</span></li>
            <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
        </ul>
    </form>
    
    {% else %}
    
    <ul class="nav navbar-nav navbar-right">
        <li><a href="{% url 'login' %}">Log in</a></li>
    </ul>
    
    {% endif %}
    
  4. 當您啟動應用程式時,不會驗證任何進階使用者,而且範本程式代碼只會轉譯 登入 連結。 連結會以 Django 專案 URL 檔案中指定的網站相對「登入」路徑為目標(DjangoWeb/DjangoWeb/urls.py),如 步驟 4(檢查 URL 路由模式)中所述。 「登入」路徑會對應至 django.contrib.auth.views.login 畫面,而畫面會接收下列資料:

    {
        'template_name': 'app/login.html',
        'authentication_form': app.forms.BootstrapAuthenticationForm,
        'extra_context':
        {
            'title': 'Log in',
            'year': datetime.now().year,
        }
    }
    

    此程式代碼會定義三個屬性:

    • template_name 會識別 app/login.html 檔案中定義的 [登入] 頁面範本。 請記住,此連結是基於網站的相對位置。 完整資料夾路徑 app/templates/app/login.html

    • extra_context 會將資訊新增至提供給範本的預設內容數據。 在此情況下,資訊會包含「登入」標題,以及日期、時間和年份。

    • authentication_form 指定要與登入程式搭配使用的表單類別。 在範本中,這個屬性值會顯示為 form 物件。 預設值為 AuthenticationForm (從 django.contrib.auth.views),但 Visual Studio 專案範本會改用專案 app/forms.py 檔案中定義的表單:

      from django import forms
      from django.contrib.auth.forms import AuthenticationForm
      from django.utils.translation import ugettext_lazy as _
      
      class BootstrapAuthenticationForm(AuthenticationForm):
          """Authentication form which uses bootstrap CSS."""
          username = forms.CharField(max_length=254,
                                  widget=forms.TextInput({
                                      'class': 'form-control',
                                      'placeholder': 'User name'}))
          password = forms.CharField(label=_("Password"),
                                  widget=forms.PasswordInput({
                                      'class': 'form-control',
                                      'placeholder':'Password'}))
      

      表單類別衍生自 AuthenticationForm,並特別覆寫使用者名稱和密碼欄位以新增佔位元文字。 Visual Studio 範本包含此明確程式代碼,假設您可能想要自定義表單,例如新增密碼強度驗證。

  5. 當使用者與應用程式互動時,會開啟 [登入] 頁面,應用程式會轉譯 login.html 範本。 變數 {{ form.username }}{{ form.password }}BootstrapAuthenticationForm 類別轉譯 CharField 表單。 另外還有一個內建區段可顯示驗證錯誤,如果您選擇新增這些服務,則為社交登入提供現成元素:

    {% extends "app/layout.html" %}
    
    {% block content %}
    
    <h2>{{ title }}</h2>
    <div class="row">
        <div class="col-md-8">
            <section id="loginForm">
                <form action="." method="post" class="form-horizontal">
                    {% csrf_token %}
                    <h4>Use a local account to log in.</h4>
                    <hr />
                    <div class="form-group">
                        <label for="id_username" class="col-md-2 control-label">User name</label>
                        <div class="col-md-10">
                            {{ form.username }}
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_password" class="col-md-2 control-label">Password</label>
                        <div class="col-md-10">
                            {{ form.password }}
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <input type="hidden" name="next" value="/" />
                            <input type="submit" value="Log in" class="btn btn-default" />
                        </div>
                    </div>
                    {% if form.errors %}
                    <p class="validation-summary-errors">Please enter a correct user name and password.</p>
                    {% endif %}
                </form>
            </section>
        </div>
        <div class="col-md-4">
            <section id="socialLoginForm"></section>
        </div>
    </div>
    
    {% endblock %}
    
  6. 當使用者在頁面窗體上選取 登入 時,Django 會嘗試驗證認證,例如進階使用者的認證:

    • 如果驗證失敗,使用者會保留在 [登入] 頁面上,且 form.errors 標籤設定為 true:

      顯示使用者在 Django 登入程式中輸入不正確認證的訊息螢幕快照。

    • 如果驗證成功,Django 會在 [next] 字段中開啟相對 URL,<input type="hidden" name="next" value="/" />,在此案例中為 [首頁] 頁面 (/)。

  7. 當應用程式在使用者通過驗證之後轉譯「首頁」頁面時,user.is_authenticated 屬性會在轉譯 loginpartial.html 範本時為 true。 在此情況下,導覽列會顯示 Hello(使用者名稱) 訊息,而 登出 選項會取代 登入 選項:

    顯示已驗證使用者的更新導覽列的螢幕快照,其中包含 Hello 訊息和 [註銷] 選項。

    您可以在應用程式程式代碼的其他部分使用 user.is_authenticated 屬性來檢查驗證。

存取 Django 系統管理員介面

若要檢查已驗證的使用者是否獲得存取特定資源的授權,您需要從資料庫擷取使用者特定許可權。

特別是進階使用者或系統管理員,會使用網站相對 URL /admin//admin/doc/,獲得存取內建 Django 系統管理員介面的授權。 如需詳細資訊,請參閱 使用 Django 驗證系統 (Django docs)。

若要啟用 Django 系統管理員介面的存取權,請遵循下列步驟:

  1. docutils Python 套件安裝到您的環境中。 如需指示,請參閱 安裝 Python 環境的套件

  2. [方案總管]中,展開 Django 專案資料夾,DjangoWeb/DjangoWeb/。 下列步驟會更新此資料夾中的數個檔案。

  3. 開啟 Django 專案的 urls.py 檔案,並修改內容,如下所示:

    1. 在檔案頂端,將下列 URL 的套件匯入新增至目前列表的結尾:

      from django.conf.urls import include
      
    2. 匯入清單之後,新增下列語句:

      admin.autodiscover()
      
    3. 找出 urlpatterns 定義,並在 之前的 'admin/' 項目新增下列路徑條目

      path('admin/doc/', include('django.contrib.admindocs.urls')),
      
  4. 開啟 Django 專案的 settings.py 檔案,並找出 INSTALLED_APPS 集合。 在 app 項目之後,立即 新增下列專案:

    'django.contrib.admindocs',
    
  5. 停止並重新啟動 Django Web 應用程式。

  6. 在瀏覽器的 [URL 位址] 字段中,將應用程式的頁面檢視變更為 /admin//admin/doc/ 路由。 這些頁面提供進階使用者存取 Django 系統管理工作,例如建立使用者或組帳戶、變更密碼,以及檢視 Django 檔:

    顯示 Django 檔範例頁面檢視的螢幕快照,顯示 Django Web 應用程式中已驗證進階使用者的範例頁面檢視。

探索登出模式

進階使用者有兩種方式可以註銷並結束已驗證的會話。 Django Web 應用程式包含導覽列上的 [註銷] 選項,Django 系統管理網站會提供 [註銷] 選項。

Django 後台網站登出

如果超級使用者在 Django 系統管理網站上檢視頁面,他們可以在網站導覽列上選取 [註銷]。 瀏覽器會重新整理,顯示該網站的 [登出] 頁面:

超級使用者登出 Django 系統管理網站後顯示 [登出] 頁面的螢幕快照。

在此頁面上,使用者有兩個選項,首頁再次登入。 這兩個選項都會將用戶傳回 Django 系統管理網站 (/admin) 的 [首頁] 頁面,其中會提示使用者重新輸入其認證。

顯示 Django 系統管理網站的 [登入] 對話框的螢幕快照。

從 Django Web 應用程式登出

如果超級使用者正在 Django 網頁應用程式中檢視頁面,例如「關於」或「聯繫」,他們可以在 Django 網頁應用的導覽列上選取 退出。 註銷行為最少。 它只會結束已驗證的會話,並將使用者流覽回應用程式「首頁」頁面。

您可以改進註銷行為,以提供使用者更完整的資訊:

  1. 在 [方案總管] 中,展開專案的 app/templates/app 資料夾,然後開啟 loginpartial.html 檔案。

  2. 在範本檔案中,請注意,註銷 連結只會對網站相對 URL 路徑 “/login” (href="{% url 'login' %}") 執行 HTTP POST (action="/logout" method="post") 作業。

    {% if user.is_authenticated %}
    <form id="logoutForm" action="/logout" method="post" class="navbar-right">
       {% csrf_token %}
       <ul class="nav navbar-nav navbar-right">
          <li><span class="navbar-brand">Hello {{ user.username }}!</span></li>
          <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
       </ul>
    </form>
    
    {% else %}
    
    <ul class="nav navbar-nav navbar-right">
       <li><a href="{% url 'login' %}">Log in</a></li>
    </ul>
    
    {% endif %}
    

    內建檢視 django.contrib.auth.views.logout 函式會處理此登出過程。

    目前的系統行為不會顯示任何讓使用者知道他們已經登出的使用者介面。 此程式只會根據 Django 專案 URL 檔案中定義的 'logout/' 路徑模式,流覽回 Django Web 應用程式「首頁」頁面(DjangoWeb/DjangoWeb/urls.py):

     path('logout/', LogoutView.as_view(next_page='/'), name='logout'),
    

    若要顯示更多資訊的註銷確認,您可以為應用程式建立一個「註銷」頁面。

  3. app/templates/app 資料夾中,建立名為 loggedoff.html的新 HTML 範本檔案。

  4. 將下列內容新增至新的範本檔案:

    {% extends "app/layout.html" %}
    {% block content %}
    <h3>You have been logged off</h3>
    {% endblock %}
    
  5. 在 Django 專案的 URL 檔案中,DjangoWeb/DjangoWeb/urls.py,變更 'logout/' 路徑的 URL 模式,如下所示:

    path('logout/', LogoutView.as_view(template_name='app/loggedoff.html'), name='logout'),
    

    更新的程式代碼會新增 template_name 屬性,以搭配 "登出" 頁面的新 HTML 範本。

  6. 停止並重新啟動 Django Web 應用程式。 再次登入,然後選取 登出。 此次,應用程式會顯示更具資訊性的訊息給使用者,以確認他們已登出。

    螢幕快照,顯示 Django Web 應用程式的更新註銷行為,並在 [註銷] 頁面上顯示訊息。

  7. 停止伺服器並關閉應用程式瀏覽器視窗。

將專案儲存至版本控制

如果您在本教學課程系列的整個過程中將您的 Visual Studio 解決方案提交到版本控制系統,現在是進行另一個提交的好時機。 請遵循本教學課程系列中的 步驟 2(將變更提交到版本控制)的指示

您的解決方案應該符合 GitHub 上的教學課程原始程式碼:Microsoft/python-sample-vs-learning-django

在表單元素中使用 {% csrf_token %} 標記

{% csrf_token %} 標記包括 Django 的內建 跨網站請求偽造(csrf)防護機制(Django 檔案)。 您通常會將此標籤新增至任何牽涉到 POST、PUT 或 DELETE 要求方法的專案,例如表單。 範本渲染函數(render)然後插入必要的保護。

教學課程評論

恭喜您完成 Visual Studio 中 Django 的本教學課程。

在本教學課程中,您已瞭解如何:

  • 在 Visual Studio 中使用各種範本建置不同類型的 Django 專案
  • 使用多個頁面建立 Django Web 應用程式
  • 使用範本建立不同的路由和頁面檢視
  • 提供靜態檔案、新增頁面,以及使用範本繼承
  • 提供受限制應用程式頁面和功能的已驗證存取權,以及 Django 系統管理介面