次の方法で共有


チュートリアル: Visual Studio で Django を使用してユーザーを認証する

この記事では、チュートリアル シリーズの手順 5 Visual Studioで Django Web フレームワークを操作する方法について説明します。

認証は、Web アプリの一般的な要件です。 Visual Studio の Django Web Project テンプレートには、Django プロジェクトの settings.py ファイルでの認証に必要なすべてのモジュールが用意されています。 このチュートリアル シリーズの手順 4 では、このテンプレートを使用して Django Web アプリを作成します。 手順 5 では、テンプレートの認証機能を調べ、実行中のアプリの機能を操作します。

チュートリアルの手順 5 では、次の方法を学習します。

  • Visual Studio の Django Web プロジェクト テンプレートで認証フローを調べる
  • 認証プロセスをサポートするコードを調べる
  • Django 管理者インターフェイスへのアクセスを有効にするようにコードを変更する
  • Django Web アプリを実行し、認証機能を使用する

前提 条件

  • Django Web Project テンプレート (DjangoWeb) に基づく Visual Studio ソリューションと Django Web アプリ。 手順 4: 完全な Django Web プロジェクト テンプレートを使用、このアプリを作成する方法について説明します。

  • Django Web アプリには、スーパー ユーザー (管理者) アカウントが必要です。 手順 4 (Django スーパー ユーザーの作成)、スーパー ユーザー資格情報を作成する方法について説明します。

  • Django テンプレートのバージョン、Visual Studio プロジェクトと Django プロジェクト、Mac での Python 開発の詳細については、このチュートリアル シリーズの手順 1 の「前提条件の」セクションを参照してください。

認証フローを調べる

このセクションでは、Django Web アプリ用の Django Web Project テンプレートによって提供される既定の認証フローについて説明します。

  1. Visual Studio で、[デバッグ ]>[デバッグの開始] (F5) を選択して、Django Web アプリ (DjangoWeb) を起動します。

  2. ブラウザーでアプリが開いたら、ナビゲーション バーの右側にある [ログイン オプションに注目してください。

    実行中の Django Web アプリのナビゲーション バーの [ログイン] オプションを示すスクリーンショット。

    実行中の Django アプリには、ホーム連絡先ログイン オプションの 3 つのページ オプションがあるナビゲーション バーがあります。 認証構成では、すべてのユーザーが [ホーム]、[バージョン情報]、[連絡先] の各ページでコンテンツを表示できます。

  3. Django Web アプリへの認証済みアクセスの場合、指定されたスーパー ユーザーは ログイン オプションを使用できます。このオプションを使用すると、[ログイン] ページが開きます。

    実行中の Django Web アプリのスーパー ユーザーの [ログイン認証] ページを示すスクリーンショット。

  4. スーパー ユーザーがサインインすると、サイトの制限付きページ ビューにアクセスし、管理タスクを完了できます。

    Django スーパー ユーザーが使用できるページ ビューの 1 つと、[ログアウト] オプションを使用して更新されたナビゲーション バーを示すスクリーンショット。

  5. スーパー ユーザーは、ログオフ オプションを使用して Django Web アプリからサインアウトし、認証されていないユーザーとして Django Web アプリの [ホーム] ページに戻ることができます。

以降のセクションでは、スーパー ユーザーの 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. アプリを起動すると、スーパー ユーザーは認証されず、テンプレート コードは ログイン リンクのみをレンダリングします。 このリンクは、の手順 4 (URL ルート パターンの確認) で説明されているように、Django プロジェクトの URL ファイル (DjangoWeb/DjangoWeb/urls.py) で指定されたサイト相対 "ログイン" パス対象とします。 "login" ルートは django.contrib.auth.views.login ビューにマップされ、ビューは次のデータを受け取ります。

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

    このコードでは、次の 3 つのプロパティを定義します。

    • template_name は、アプリ/login.html ファイルで定義されている [ログイン] ページのテンプレートを識別します。 このリンクはサイトの相対リンクであることに注意してください。 完全なフォルダー パスは、app/templates/app/login.htmlです。

    • extra_context は、テンプレートに指定された既定のコンテキスト データに情報を追加します。 この場合、情報には、日付、時刻、および年と共に "ログイン" タイトルが含まれます。

    • authentication_form ログイン プロシージャで使用するフォーム クラスを指定します。 テンプレートでは、このプロパティ値は form オブジェクトとして表示されます。 既定値は (django.contrib.auth.viewsから) AuthenticationForm されますが、Visual Studio プロジェクト テンプレートでは、代わりにプロジェクトの アプリ/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 フィールド (<input type="hidden" name="next" value="/" />) に相対 URL を開きます。この場合は "ホーム" ページ (/)。

  7. ユーザーの認証後にアプリが "ホーム" ページをレンダリングする場合、loginpartial.html テンプレートがレンダリングされるときに、user.is_authenticated プロパティは true になります。 この場合、ナビゲーション バーに Hello (ユーザー名) メッセージが表示され、[ログオフ] オプションが [ログイン] オプション 置き換えられます。

    [Hello message and Log off]\(Hello メッセージとログオフ\) オプションを使用して認証されたユーザーの更新されたナビゲーション バーを示すスクリーンショット。

    アプリ コードの他の部分で user.is_authenticated プロパティを使用して、認証を確認できます。

Django 管理者インターフェイスにアクセスする

認証されたユーザーが特定のリソースへのアクセスを許可されているかどうかを確認するには、データベースからユーザー固有のアクセス許可を取得する必要があります。

スーパー ユーザーまたは管理者は、特に、サイトの相対 URL /admin//admin/doc/を使用して、組み込みの Django 管理者インターフェイスにアクセスする権限を持ちます。 詳細については、「Django 認証システム の使用 (Django ドキュメント)」を参照してください。

Django 管理者インターフェイスへのアクセスを有効にするには、次の手順に従います。

  1. docutils Python パッケージを環境にインストールします。 手順については、「Python 環境のパッケージをインストールする」を参照してください。

  2. ソリューション エクスプローラー で、DjangoWeb/DjangoWeb/ Django プロジェクト フォルダーを展開します。 次の手順では、このフォルダー内のいくつかのファイルを更新します。

  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 Web アプリで認証されたスーパー ユーザーの Django ドキュメントのページ ビューの例を示すスクリーンショット。

ログオフ動作を調べる

スーパー ユーザーが認証されたセッションをログオフして終了するには、2 つの方法があります。 Django Web アプリには、ナビゲーション バーに Log off オプションが含まれており、Django 管理サイトには Log Out オプションが用意されています。

Django 管理サイトからログアウトする

スーパー ユーザーが Django 管理サイトでページを表示している場合は、サイト ナビゲーション バーで [ログアウト] 選択できます。 ブラウザーが更新され、サイトの [ログオフ済み] ページが表示されます。

スーパー ユーザーが Django 管理サイトからログアウトした後の [ログアウト] ページを示すスクリーンショット。

このページでは、ユーザーが選べるオプションが2つあります: ホーム再度ログイン。 どちらのオプションでも、ユーザーは Django 管理サイト (/admin) の [ホーム] ページに戻り、資格情報の再入力を求められます。

Django 管理サイトの [ログイン] ダイアログを示すスクリーンショット。

Django Web アプリからログオフする

スーパー ユーザーが Django Web アプリのページ ("About" や "Contact" など) を表示している場合は、Django Web アプリのナビゲーション バー [ログオフ] を選択できます。 ログオフ動作は最小限です。 認証されたセッションが終了し、ユーザーがアプリの [ホーム] ページに戻ります。

ユーザーにとってより有益になるように、ログオフ動作をやり直すことができます。

  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 関数は、このログアウト プロセスを処理します。

    現在の動作では、ユーザーがログオフしたことをユーザーに知らせる UI は表示されません。 このプロセスでは、Django プロジェクトの URL ファイル (DjangoWeb/DjangoWeb/urls.py) で定義されている 'logout/' パス パターンに従って、ユーザーを Django Web アプリの "ホーム" ページに戻すだけです。

     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'),
    

    更新されたコードは、"ログオフ" ページの新しい HTML テンプレートを操作する template_name プロパティを追加します。

  6. Django Web アプリを停止して再起動します。 もう一度サインインし、[ログオフ] 選択します。 今回は、ユーザーがログオフしていることを確認するためのより有益なメッセージがアプリに表示されます。

    [ログオフ] ページにメッセージが表示された Django Web アプリの更新されたログオフ動作を示すスクリーンショット。

  7. サーバーを停止し、アプリケーション ブラウザー ウィンドウを閉じます。

プロジェクトをソース管理に保存する

このチュートリアル シリーズの過程で Visual Studio ソリューションをソース管理にコミットしている場合は、もう一度コミットすることをお勧めします。 このチュートリアル シリーズの 手順 2 (ソース管理への変更をコミットする) の手順に従います。

ソリューションは GitHub のチュートリアルソースコード(Microsoft/python-sample-vs-learning-django )と一致する必要があります。

フォーム要素で {% csrf_token %} タグを使用する

{% csrf_token %} タグには Django の組み込みのクロスサイト リクエスト フォージェリ (csrf) 保護 (Django docs) が含まれています。 通常、このタグは、フォームなどの POST、PUT、または DELETE 要求メソッドを含む要素に追加します。 テンプレート レンダリング関数 (render) は、必要な保護を挿入します。

チュートリアル のレビュー

Visual Studio の Django でこのチュートリアルを完了しました。

このチュートリアルでは、次の方法を学習しました。

  • Visual Studio でさまざまなテンプレートを使用して、さまざまな種類の Django プロジェクトをビルドする
  • 複数のページを含む Django Web アプリを作成する
  • テンプレートを使用してさまざまなルートとページ ビューを作成する
  • 静的ファイルの提供、ページの追加、テンプレートの継承の使用
  • 制限付きアプリ ページと機能と Django 管理インターフェイスへの認証済みアクセスを提供する