Djangoの認証システムを使用する¶
このドキュメントでは、デフォルト設定でのDjangoの認証システムの使用方法を説明します。この設定は、タスクの適切な範囲を管理することで、最も一般的なプロジェクトのニーズにかなうよう徐々に発展してきました。そして、パスワードや権限の入念な実装を持っています。デフォルトの認証システムからの変更が必要なプロジェクトのために、Djangoは認証システムの広範囲の 拡張とカスタマイズ をサポートします。
Djangoの認証は、認証 (authentication) 機能と認可 (authorization) 機能の両方を提供しています。そして、一般的に、これらの機能を合わせて認証システムと呼びます。
User
オブジェクト¶
User
オブジェクトは、認証システムの中核です。一般的に、このオブジェクトはあなたのサイトに関係する人々を表し、アクセスを制限すること、ユーザ情報を登録すること、コンテンツを作成者と関連付けることを可能にする際などに利用されます。
Djangoの認証フレームワークにはUserクラスという、ただひとつのクラスのみが存在します。すなわち、 'superusers'
または admin 'staff'
ユーザは、Userオブジェクトと異なるクラスではなく、特別な属性セットを持ったUserオブジェクトなのです。
デフォルトのユーザの主要な属性は次のとおりです。
仕様については 完全な 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 adminをインストールしている場合は、 インタラクティブにユーザを作成する こともできます。
スーパーユーザを作成する¶
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*
は、コマンドラインからユーザのパスワードを変更する方法を提供します。ユーザのパスワードを変更するよう促されたら、パスワードを 2 回入力してください。2 つのパスワードが一致した場合、新しいパスワードが直ちに有効になります。ユーザを指定しない場合、コマンドは、現在のシステムユーザとユーザ名が一致するユーザのパスワードを変更するよう試みます。
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ページ にて、ユーザのパスワードを変更することも可能です。
また、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
を使ってください。Changed in Django 5.0:aauthenticate()
関数が追加されました。
Web リクエストにおける認証¶
Django は リクエストオブジェクト
に対して認証システムを接続させるのに セッション とミドルウェアを利用します。
これらは、現在のユーザーを示すすべてのリクエストに 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()
メソッドが追加されました。
ユーザーをログインさせる方法¶
現在のセッションに接続したい認証ユーザーがいる場合、login()
関数を使用できます。
- alogin(request, user, backend=None)¶
非同期バージョン:
alogin()
ビューからユーザーをログインさせるには、
login()
を利用します。この関数はHttpRequest
オブジェクトとUser
オブジェクトを受け取ります。login()
は、Django のセッションフレームワークを利用して、セッション中のユーザー ID を保存します。匿名セッション中に設定されたデータは、ユーザーがログインした後もセッション内に保持されることに注意してください。
以下の例では、
authenticate()
とlogin()
の2つの関数の使用方法の例です。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. ...
Changed in Django 5.0:alogin()
関数が追加されました。
認証バックエンドの選択¶
ユーザーがログインするとき、そのユーザーの ID と認証に使用したバックエンドは、ユーザーのセッション内に保存されます。これにより、同じ 認証バックエンド が今後のリクエストでユーザーの詳細情報を取得できるようになります。セッション内に保存される認証バックエンドは、以下のように選択されます。
オプションの引数
backend
が与えられている場合は、その値を利用する。存在すれば属性
user.backend
の値を利用する。authenticate()
は返すユーザーオブジェクトに属性値user.backend
を設定するので、これにより、authenticate()
とlogin()
をペアリングできます。AUTHENTICATION_BACKENDS
に設定が1つだけあれば、そのbackend
を利用する。いずれにも該当しなかった場合、例外が送出される。
1 もしくは 2 においては、引数 backend
あるいは属性値 user.backend
は(AUTHENTICATION_BACKENDS
で定義されているのと同様に)ドット付きのインポート先を示すパスの文字列でなければなりません。
ユーザーをログアウトさせる方法¶
- alogout(request)¶
非同期バージョン:
alogout()
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()
を呼び出すと、現在処理しているリクエストに対応したセッション情報は完全に破棄されます。その時点までに存在している全てのデータが削除されます。これは、別の人物が同じウェブブラウザを利用してログインし、前のユーザーのセッションにアクセスして使用してしまう事態を防ぐためです。ログアウトした直後でも利用できる何らかの情報をセッションに保存したい場合は、django.contrib.auth.logout()
を呼び出した 後 に行ってください。Changed in 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/
もしユーザがログインしていれば、通常通りビューを処理します。ビューのコードの中ではユーザがログインしているかを意識しなくて良いのです。
デフォルトでは、認証に成功したユーザがリダイレクトされる先のパスは
"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
に値を持たせた場合、ログインテンプレートもカスタマイズする必要があるでしょう。これは、リダイレクト先のパスを格納しているテンプレートコンテキスト変数が、キーとして (デフォルトの)"next"
でなくredirect_field_name
の値を使用してしまうためです。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 path("accounts/login/", auth_views.LoginView.as_view()),
settings.LOGIN_URL
は、ビュー関数名と 命名された URL パターン も受け付けます。これにより、設定を更新せずに URLconf 内でログイン用ビューを自由に再マッピングできます。
注釈
login_required
デコレータはユーザーのフラグ is_active
をチェック「しません」が、デフォルトの AUTHENTICATION_BACKENDS
は非アクティブなユーザを拒否します。
参考
もし Django の管理画面向けにカスタムビューを実装している (あるいはビルトインのビューが利用しているのと同じ認可チェックが必要である) 場合は、django.contrib.admin.views.decorators.staff_member_required()
デコレータが login_required()
の代替手段となるかもしれません。
非同期ビュー関数のラップをサポートしました。
LoginRequiredMixin
mixin¶
クラスベースのビュー を使う際、 LoginRequiredMixin
を使うことで login_required
と同じ動作をさせることができます。 この mixin は、継承リストの一番左に記述される必要があります。
- class LoginRequiredMixin[ソース]¶
ビューがこの mixin を使う場合、認証されていないユーザによるすべてのリクエストは、ログインページにリダイレクトされるか、HTTP 403 Forbidden エラー表示となります。これは、
raise_exception
パラメータにて設定します。次のように
AccessMixin
のパラメータを設定することで、認可されていないユーザの処理をカスタマイズできます。from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): login_url = "/login/" redirect_field_name = "redirect_to"
注釈
login_required
デコレータと同様に、この mixin はユーザの is_active
フラグをチェックしません。しかし、デフォルトの AUTHENTICATION_BACKENDS
が非アクティブのユーザを拒否します。
login_not_required
デコレータ¶
LoginRequiredMiddleware
をインストールすると、すべてのビューがデフォルトで認証を必要とするようになります。ログインビューなど一部のビューでは、この動作を無効にしなければならないでしょう。
- login_not_required()[ソース]¶
LoginRequiredMiddleware
がインストールされているときに、このビューへの未認証リクエストを許可します。
テストをパスしたログイン済みユーザのアクセスを制限する¶
特定の権限やその他のテストに基づいてアクセスを制限するには、前のセクションで説明したのと基本的に同じことを行います。
直接ビューで request.user
に対してテストを実行できます。たとえば、このビューは、ユーザが希望するドメインのメールを持っているかどうかをチェックし、持っていない場合はログインページにリダイレクトします:
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()
はオプションで2つの引数を取ります: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): ...
Changed in Django 5.1:非同期ビュー関数のラップおよび非同期テストcallableのサポートが追加されました。
- 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()
メソッドをオーバーライドすることで、(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()
メソッドと同じように、パーミッション名は"<app label>.<permission codename>"
という形式を取ります (たとえば、polls
アプリケーションのモデルに対するパーミッションはpolls.add_choice
となります)。この場合、ビューにアクセスするためには、ユーザはすべてのパーミッションを持っている必要があります。
また、
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
で、ログインしているユーザーが必要なすべての権限を持っていない場合に、リダイレクトループを回避できます。
非同期ビュー関数のラップをサポートしました。
PermissionRequiredMixin
ミックスイン¶
クラスベースのビュー にパーミッションチェックを適用するには、 PermissionRequiredMixin
を使用します:
- class PermissionRequiredMixin[ソース]¶
このミックスインは
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
のパラメータを指定することで、認可されていないユーザの処理をカスタマイズできます。これらのメソッドをオーバーライドすることもできます:
- get_permission_required()[ソース]¶
ミックスインが使用するパーミッション名のイテラブルを返します。デフォルトは
permission_required
属性で、必要に応じてタプルに変換されます。
- has_permission()[ソース]¶
現在のユーザがデコレートされたビューを実行する権限を持っているかどうかを真偽値で返します。デフォルトでは、
has_perms()
をget_permission_required()
によって返されたパーミッションのリストで呼び出した結果を返します。
認証ビュー¶
Django の提供する複数のビューを使って、ログイン、ログアウト、パスワード管理を行うことができます。これらは ビルトインの認証フォーム を使用しますが、独自のフォームを使用することもできます。
認証ビュー向けのデフォルトのテンプレートはありません。使用したいビューのテンプレートを自分で作成する必要があります。テンプレートのコンテキストは各ビューに記述されているので、すべての認証ビュー を参照してください。
ビューを使用する¶
プロジェクト内でこれらのビューを実装するには、いくつかの方法があります。最も簡単なのは、django.contrib.auth.urls
で提供される URLconf を自分の 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
引数を指定します。引数指定の方法の 1 つは、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 を要求することで、訪問者があなたのサイトで認証されているかどうかを判断できます。この 「ソーシャルメディアのフィンガープリンティング」 による情報漏洩を避けるには、すべての画像と favicon を別ドメインでホストしてください。redirect_authenticated_user
を有効にすると、permission_required()
デコレータを使用したときにraise_exception
パラメータを使用しない限り、リダイレクトループが発生する可能性があります。
- success_url_allowed_hosts¶
ログイン後にリダイレクトしても安全なホストの
set
を、request.get_host()
に加えて指定します。デフォルトは空のset
です。
- get_default_redirect_url()[ソース]¶
ログイン後にリダイレクトするURLを返します。デフォルトの実装では、
next_page
が指定されていれば解決して返し、そうでなければLOGIN_REDIRECT_URL
を返します。
以下は
LoginView
の機能です:GET
で呼び出すと、同じURLにPOSTするログインフォームを表示します。これについてはもう少し詳しく説明します。ユーザが送信した認証情報を使って
POST
経由で呼び出された場合、ユーザをログインさせようとします。ログインに成功すると、ビューはnext
で指定された URL にリダイレクトします。もしnext
が指定されていない場合、settings.LOGIN_REDIRECT_URL
(デフォルトは/accounts/profile/
) にリダイレクトします。ログインが成功しなかった場合、ログインフォームを再表示します。
デフォルトでは
registration/login.html
と呼び出されるログインテンプレートのhtmlを提供するのはあなたの責任です。このテンプレートには以下の4つのテンプレートコンテキスト変数が渡されます:form
:AuthenticationForm
を表すForm
オブジェクトです。next
: ログイン成功後にリダイレクトするURL。これはクエリ文字列を含むこともできます。site
:SITE_ID
設定に基づく現在のSite
。サイトフレームワークがインストールされていない場合、RequestSite
のインスタンスに設定されます。このインスタンスは現在のHttpRequest
からサイト名とドメインを派生させます。site_name
:site.name
のエイリアス。サイトフレームワークがインストールされていない場合、request.META['SERVER_NAME']
の値がセットされます。サイトについての詳細は "sites" フレームワーク を参照してください。
もしテンプレート
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")),
また、ログイン後にリダイレクトする URL を含む
GET
フィールドの名前を指定するには、redirect_field_name
を使います。このフィールドは、デフォルトでは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
です。
- redirect_field_name¶
ログアウト後にリダイレクトする URL を含む
GET
フィールドの名前。デフォルトは'next'
です。GET
パラメータが渡された場合、next_page
URL を上書きします。
- extra_context¶
テンプレートに渡されるデフォルトコンテキストデータに追加されるコンテキストデータの辞書。
- success_url_allowed_hosts¶
request.get_host()
に加えて、ログアウト後にリダイレクトしても安全なホストのset
を指定します。デフォルトは空のset
です。
テンプレート コンテキスト:
title
: 文字列 "Logged out"。これはローカライズされています。site
:SITE_ID
設定に基づく現在のSite
。サイトフレームワークがインストールされていない場合、RequestSite
のインスタンスに設定されます。このインスタンスは現在のHttpRequest
からサイト名とドメインを派生させます。site_name
:site.name
のエイリアス。サイトフレームワークがインストールされていない場合、request.META['SERVER_NAME']
の値がセットされます。サイトについての詳細は "sites" フレームワーク を参照してください。
- 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
を受け付けるカスタム "change password" フォームです。このフォームはユーザのパスワードを実際に変更する役割を持ちます。デフォルトは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
パスワードをリセットするために使われる 1 回限り有効なリンクを生成し、ユーザがパスワードをリセットできるようにします。そのリンクはユーザーが登録したメールアドレスに送信されます。
このビューは、以下の条件が満たされた場合にメールを送信します:
入力されたメールアドレスがシステムに存在すること。
要求されたユーザーがアクティブであること (
User.is_active
がTrue
であること)。要求されたユーザが使用可能なパスワードを持っていること。LDAP のような外部認証ソースを使用している場合、悪用を防ぐために、使用不可能なパスワード (
set_unusable_password()
を参照) のフラグが付けられたユーザはパスワードのリセットを要求できません。
これらの条件のいずれかが満たされ ない 場合、メールは送信されませんが、ユーザーにはエラーメッセージは送信されません。これは、潜在的な攻撃者への情報漏洩を防ぐためです。この場合にエラーメッセージを表示したい場合は、
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¶
1 回限りのリンクをチェックするためのクラスのインスタンス。デフォルトは
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 が True
) だけがパスワードをリセットできます。site_name
:site.name
のエイリアス。サイトフレームワークがインストールされていない場合、request.META['SERVER_NAME']
の値がセットされます。サイトについての詳細は "sites" フレームワーク を参照してください。domain
:site.domain
の別名 (エイリアス) 。サイトのフレームワークをインストールしていない場合、request.get_host()
の値がセットされます。protocol
: http か https です。uid
: 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 %}
表題のテンプレートにも同じテンプレートコンテキストが使われます。表題は 1 行のプレーンテキスト文字列の必要があります。
- 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')[ソース]¶
ログインページにリダイレクトし、ログイン成功後にもう 1 つの URL に戻ります。
必須の引数:
next
: ログイン成功後のリダイレクト先の URL です。
オプションの引数:
login_url
: リダイレクト先のログインページのURL。省略時のデフォルトはsettings.LOGIN_URL
です。redirect_field_name
: ログイン後のリダイレクト先の URL を含むGET
フィールドの名前。指定されたGET
パラメータが与えられた場合、next
をオーバーライドします。
ビルトインのフォーム¶
ビルトインのビューを使いたくないけれども、ビューの機能を再利用したいと考えている場合、認証システムが提供しているビルトインのフォームを使うことができます。ビルトインのフォームは django.contrib.auth.forms
にあります。
注釈
ビルトインの認証フォームは、扱うユーザーモデルについて一定の前提に基づいて設計されています。なので、もし 独自のユーザーモデル を使っている場合は、 認証システムに対して自分自身のフォームを定義する必要がある可能性があります。詳しくは、独自のユーザーモデルでビルトインの認証フォームを使用する を参照してください。
- class AdminPasswordChangeForm[ソース]¶
管理インターフェースでユーザーのパスワードを変更するためのフォームで、
unusable password
を設定する機能も含まれています。これにより、パスワードベースの認証でそのユーザーがログインできないようにブロックすることが可能です。第 1 引数として
user
を取ります。Changed in Django 5.1:パスワードベースの認証を無効化(または再有効化)するオプションが追加されました。
- class AdminUserCreationForm[ソース]¶
- New in Django 5.1.1.
新しいユーザーを作成するために管理インターフェースで使用されるフォームで、
UserCreationForm
を継承しています。このフォームには、デフォルトで有効になっている追加の
usable_password
フィールドが含まれています。usable_password
が有効な場合、password1
とpassword2
が空でなく一致していることを確認し、validate_password()
を使用してパスワードを検証し、set_password()
でユーザーのパスワードを設定します。usable_password
が無効な場合、パスワードの検証は行われず、set_unusable_password()
を呼び出してパスワードベースの認証を無効にします。
- class AuthenticationForm[ソース]¶
ユーザーログインのためのフォームです。
第 1 引数として
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
という3つのフィールドがあります。password1
とpassword2
が一致するか確認し、validate_password()
を使ってパスワードを検証します。そして、set_password()
を使ってユーザのパスワードをセットします。
- class PasswordResetForm[ソース]¶
ユーザのパスワードリセットするための 1 回限りのリンクを生成してメール送信するためのフォームです。
- 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 %}
2段階の属性ルックアップを真偽値として評価することは 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 %}
admin 内でユーザを管理する¶
django.contrib.admin
と django.contrib.auth
の両方をインストールしていれば、admin でユーザ、グループおよびパーミッションを見たり管理することが簡単にできます。ユーザは通常の Django モデルと同じく作成や削除ができます。グループも作成することができ、パーミッションはユーザやグループにアサインできます。admin でのユーザー編集のログも保管および表示されます。
ユーザを作成する¶
管理インデックスページの「Auth」セクションに「Users」へのリンクが表示されるはずです。「Add user」管理ページは標準の管理ページとは異なり、他のユーザーフィールドを編集する前にユーザー名とパスワードを選択する必要があります。また、このページでは、ユーザー名を選択してパスワードベースの認証を無効にすることもできます。
また、Django の admin サイトを使用してユーザアカウントを作成できるようにするには、ユーザを追加 および 変更する権限をユーザに与える必要があります (つまり "Add user" と "Change user" パーミッション)。あるアカウントにユーザの追加権限のみが与えられ変更権限がない場合、そのアカウントはユーザを追加できません。なぜなら、追加権限によってスーパーユーザを作成することができ、そのスーパーユーザを使って他のユーザーを変更することができてしまうからです。 そのため、Django はちょっとしたセキュリティ対策として、追加と変更の 両方 の権限を必要とするのです。
ユーザに与えるパーミッション管理の権限については、よく考える必要があります。たとえば非スーパーユーザにユーザ編集の権限を与えてしまうと、結果的に彼らにスーパーユーザと同じ能力を与えることになります。というのも、彼らはユーザ編集の権限によってユーザのパーミッションを昇格させることができるため、彼ら自身のパーミッションも昇格させられるのです!
パスワードを変更する¶
ユーザーのパスワードは管理画面には表示されません(データベースにもそのままの形では保存されません)が、パスワード保存の詳細 が表示されます。この情報には、管理者がユーザーのパスワードを変更または解除できるパスワード変更フォームへのリンクも含まれています。