手順 5: Django でユーザーを認証する
前の手順: 完全な Django Web プロジェクト テンプレートを使用する
認証は Web アプリ共通のニーズであるため、"Django Web プロジェクト" テンプレートには基本認証フローが含まれています。 いずれかの Django プロジェクト テンプレートを使用する場合、Visual Studio には Django プロジェクトの settings.py ファイルでの認証に必要なすべてのモジュールが含まれています。
この手順では、次のことを学習します。
- Visual Studio テンプレートで提供される認証フローの使用方法 (手順 5-1)
手順 5-1: 認証フローを使用する
次の手順では、認証フローを利用して、プロジェクトの各部について説明します。
プロジェクトのルートにある readme.html ファイルの指示に従ってスーパー ユーザー (管理者) アカウントをまだ作成していない場合は、すぐに作成します。
[デバッグ]>[デバッグの開始] (F5 キー) を使用して、Visual Studio からアプリを実行します。 ブラウザーにアプリが表示されたら、ナビゲーション バーの右上に [ログイン] が表示されていることを確認します。
templates/app/layout.html を開き、
<div class="navbar ...>
要素にタグ{% include app/loginpartial.html %}
が含まれていることを確認します。{% include %}
タグは、含まれているテンプレートにこの時点でインクルードされているファイルの内容を組み入れるように、Django のテンプレート システムに指示します。templates/app/loginpartial.html を開き、
{% else %}
タグと共に条件タグ{% if user.is_authenticated %}
を使用して、ユーザーが認証済みかどうかに応じて異なる 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 %}
最初にアプリを起動するときはどのユーザーも認証されていないので、このテンプレートのコードは、相対パス "login" への "ログイン" リンクのみを表示します。 (前のセクションで示したように) urls.py の指定に従って、そのルートは
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
は、ログイン ページ用のテンプレート (この場合は templates/app/login.html) を特定します。extra_context
プロパティは、テンプレートに指定された既定のコンテキスト データに追加されます。 最後に、authentication_form
は、テンプレートにform
オブジェクトとして示される、ログインに使用するフォーム クラスを定義します。 既定値はAuthenticationForm
(django.contrib.auth.views
より) です。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 boostrap 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 テンプレートには、パスワード強度の検証を追加するなど、必要に応じてフォームをカスタマイズすることを予想して、この明示的なコードが含まれています。ログイン ページに移動すると、アプリは 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 %}
フォームを送信すると、Django は資格情報 (スーパー ユーザーの資格情報など) の認証を試みます。 認証に失敗した場合、現在のページに留まりますが、
form.errors
は true に設定されます。 認証に成功した場合、Django は "next" フィールド<input type="hidden" name="next" value="/" />
にある相対 URL に移動します。この例では、ホーム ページ (/
) になっています。ここで、ホーム ページが再表示されると、loginpartial.html テンプレートが表示されるときに、
user.is_authenticated
プロパティが true になります。 その結果、Hello (<ユーザー名>) メッセージと [Log off] が表示されます。 アプリの他の部分でuser.is_authenticated
を使用して、認証を確認できます。認証済みユーザーに特定のリソースに対するアクセス権が付与されたかどうかを確認するには、ユーザー固有のアクセス許可をデータベースから取得する必要があります。 詳細については、Django 認証システムの使用に関するページ (Django docs) を参照してください。
特に、ス―パー ユーザーまたは管理者は、相対 URL "/admin/" および "/admin/doc/" を使用して、組み込みの Django 管理者インターフェイスにアクセスします。これらのインターフェイスを有効にするには、次の手順のようにします。
環境に docutils Python パッケージをインストールします。 インストールするには、requirements.txt ファイルに "docutils" を追加することをお勧めします。 次に、ソリューション エクスプローラーでプロジェクトを展開し、[Python 環境] ノードを展開し、使っている環境を右クリックし、[requirements.txt からのインストール] を選びます。
Django プロジェクトの urls.py ファイルを開き、次を追加します。
from django.conf.urls import include from django.contrib import admin admin.autodiscover() urlpatterns = [ path('admin/doc/', include('django.contrib.admindocs.urls')) ]
Django プロジェクトの settings.py ファイルで、
INSTALLED_APPS
コレクションに移動して'django.contrib.admindocs'
を追加します。アプリを再起動したときに、"/admin/" および "/admin/doc/" に移動して、追加のユーザー アカウント作成などのタスクを実行できます。
認証フローの最後の部分は、ログオフです。 loginpartial.html でわかるように、[Log off] リンクは単純に相対 URL "/login" に対する POST を実行します。これは、組み込みのビュー
django.contrib.auth.views.logout
によって処理されます。 このビューには UI が表示されず、ホーム ページへの移動のみを行います (urls.py の "^logout$" パターンで確認できます)。 ログオフ ページを表示する場合は、最初に、次のように URL パターンを変更して、"template_name" プロパティを追加し "next_page" プロパティを削除します。path('logout/', django.contrib.auth.views.logout, { 'template_name': 'app/loggedoff.html', # 'next_page': '/', }, name='logout')
次に、以下の (最小限の) 内容で templates/app/loggedoff.html を作成します。
{% extends "app/layout.html" %} {% block content %} <h3>You have been logged off</h3> {% endblock %}
結果として、次のように表示されます。
すべて完了したら、サーバーを停止し、もう一度ソース管理に変更をコミットします。
質問: <form> 要素に表示される {% csrf_token %} タグの目的は何ですか。
回答: {% csrf_token %}
タグには Django の組み込みのクロスサイト リクエスト フォージェリ (csrf) 保護 (Django docs) が含まれています。 通常、このタグは、フォームなどの POST、PUT、または DELETE 要求のメソッドに関連する任意の要素に追加します。 その後、テンプレートのレンダリング関数 (render
) により、必要な保護が挿入されます。
次のステップ
Note
このチュートリアルの途中で Visual Studio ソリューションをソース コード管理にコミットした場合は、もう 1 つのコミットを実行することをお勧めします。 ソリューションは、GitHub Microsoft/python-sample-vs-learning-django のチュートリアル ソース コードと一致するようにします。
Visual Studio で "空の Django Web プロジェクト" と "Django Web プロジェクト" の各テンプレートを全体的に確認しました。 ビューやテンプレートの使い方など、Django のすべての基本を学習しました。 また、ルーティング、認証、使用されるデータベース モデルについても確認しました。 これで、必要なビューとモデルがある独自の Web アプリを作成できるようになったはずです。
開発用コンピューター上で Web アプリを実行することは、アプリを顧客に提供するための単なる 1 つの手順です。 次の手順には以下のタスクが含まれる場合があります。
templates/404.html というテンプレートを作成して、404 ページをカスタマイズします。 このテンプレートがある場合、Django は既定のテンプレートではなくこのテンプレートを使用します。 詳細については、Django ドキュメントの「Error views」(エラー ビュー) を参照してください。
tests.py で単体テストを作成します。Visual Studio プロジェクト テンプレートには、そのための出発点が用意されています。詳細については、Django ドキュメントの「Writing your first Django app, part 5 - testing」(最初の Django アプリを作成する、パート 5 - テスト) と「Testing in Django」(Django のテスト) を参照してください。
SQLite から、PostgreSQL、MySQL、SQL Server など (これらはいずれも Azure でホストできます) の運用レベルのデータ ストアにアプリを変更します。 SQLite を使用するタイミングに関するページ (sqlite.org) で説明されているように、1 日あたりのヒット数が 100 K 未満で、トラフィックが低から中程度のサイトでは SQLite は問題なく機能します。 しかし、規模がさらに大きい場合は SQLite をお勧めしません。 また、SQLite は単一のコンピューターに制限されているため、負荷分散処理や geo レプリケーションなど、マルチサーバーのシナリオには使用できません。 他のデータベースに対する Django のサポートについては、「Database setup」(データベースの設定) を参照してください。 テーブルや BLOB のような Azure ストレージ サービスを使用する場合は、Azure SDK for Python も使用できます。
Azure DevOps などのサービスに対して、継続的インテグレーション/継続的配置パイプラインを設定します。 (Azure Repos、GitHub などの場所を使った) ソース管理を利用するだけでなく、リリースの前提条件として単体テストを自動的に実行するように Azure DevOps プロジェクトを構成することもできます。 また、運用環境にデプロイする前に、さらにテストを行うためにステージング サーバーにデプロイするようにパイプラインを構成することもできます。 さらに、Azure DevOps は App Insights などの監視ソリューションと統合されているので、アジャイル計画ツールを使用してサイクル全体に対応することができます。 詳細については、「Azure DevOps プロジェクトで Python 用の CI/CD パイプラインを作成する」、および一般的な Azure DevOps ドキュメントを参照してください。
詳しい説明
- Django でのユーザー認証 (docs.djangoproject.com)
- GitHub 上のチュートリアルのソース コード: Microsoft/python-sample-vs-learning-django