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はユーザ自身のパスワードを変更するための ビュー と フォーム を提供します。
ユーザーのパスワード変更を行う事とそのユーザーのセッションは全てログアウトされます。詳細は パスワード変更時にセッションを無効化する を参照してください。
ユーザを認証する¶
-
authenticate(request=None, **credentials)¶
-
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()関数が追加されました。
権限と認可¶
Django には組み込みのパーミッションシステムがあります。特定のユーザやユーザグループにパーミッションを割り当てる方法を提供します。
これは、Django の admin サイトでも使われていますが、独自のコード内でも自由に使えます。
Django の admin サイトは、次のように権限を使用します。
- ビューオブジェクトへのアクセスは、そのオブジェクトタイプの "view "または "change" 権限を持つユーザーに限定されます。
- "add" フォームのビューを表示してオブジェクトを追加するためのアクセスは、その種類のオブジェクトに "add" 権限を持つユーザに限定されます。
- 変更リストの表示、"change" フォームの表示、オブジェクトの変更へのアクセスは、その種類のオブジェクトに "change" 権限を持つユーザーに限定されます。
- オブジェクトの削除へのアクセスは、その種類のオブジェクトに "delete"権限を持つユーザに限定されます。
権限はオブジェクトの種類ごとだけでなく、特定のオブジェクトインスタンスごとに設定することもできます。ModelAdmin クラスによって提供される has_view_permission()、has_add_permission()、has_change_permission()、および has_delete_permission() メソッドを使用することで、同じ種類の異なるオブジェクトインスタンスに対する権限をカスタマイズすることが可能です。
User オブジェクトは 2 つの多対多のフィールド、groups および user_permissions を持っています。User オブジェクトは、他の Django モデル と同様の方法で、関連を持っているオブジェクトにアクセスできます。
myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()
デフォルトの権限¶
INSTALLED_APPS 設定に django.contrib.auth がリストされていると、インストー ルしたアプリケーションで定義された Django モデルごとに、追加、変更、削除、表示 の 4 つのデフォルトパーミッションが作成されます。
これらの権限は manage.py migrate 実行時に作成されます。INSTALLED_APPS に django.contrib.auth を追加後初めての migrate を実行した場合は、新たにインストールされるモデルに対してと同様、それまでに作成されたモデルに対してもデフォルトの権限が作成されます。以後 manage.py migrate (この権限を作成する関数は post_migrate シグナルに接続されています)を実行する度作成されるモデルに対してデフォルトの権限が作成されます。
app_label が foo のアプリケーションと、Bar という名前のモデルがあると想定すると、基本的な権限をテストするには、以下のように使用する必要があります。
- 追加:
user.has_perm('foo.add_bar') - 変更:
user.has_perm('foo.change_bar') - 削除:
user.has_perm('foo.delete_bar') - 表示:
user.has_perm('foo.view_bar')
Permission モデルが直接アクセスされることはほとんどありません。
グループ¶
django.contrib.auth.models.Group モデルはユーザーを分類する汎用的な方法であるため、対象となるユーザーに権限や、何らかのラベルを適用できます。1つのユーザーは複数のグループに属することが可能です。
グループに属するユーザーは、そのグループに付与された権限を自動的に持ちます。たとえば、Site editors グループが can_edit_home_page 権限を持っていた場合、そのグループ内のすべてのユーザーは、その権限を持つことになります。
権限に限らず、グループはユーザーを分類して、ラベルや拡張された機能を与えるために便利な手段です。たとえば、Special users というグループを作成して、そのグループのメンバーに対してサイトのメンバー限定の領域にアクセスする権限を付与したり、メンバー限定のメールを送るコードを書いたりすることも可能です。
プログラムによる権限の作成¶
カスタム権限 は、モデルの Meta クラス内に定義でき、権限を直接作成することも可能です。たとえば、myapp 内の BlogPost モデルに対する権限 can_publish は、以下のように作成できます。
from myapp.models import BlogPost
from django.contrib.auth.models import 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 に割り当てることができます。
プロキシモデルには独自のコンテンツタイプが必要です
プロキシモデルのパーミッション を作成したい場合は、次のように ContentTypeManager.get_for_model() に for_concrete_model=False を渡して、適切な ContentType を取得してください。
content_type = ContentType.objects.get_for_model(
BlogPostProxy, for_concrete_model=False
)
権限のキャッシュ¶
ModelBackend は、権限チェックのために最初に取得する必要があるユーザーオブジェクト上の権限をキャッシュします。権限は (たとえば admin 内で) 付与された直後に権限をチェックすることはないため、これは、通常のリクエスト-レスポンスのサイクルでは問題ありません。たとえばテストやビューなどで、権限を付与した直後に権限の確認を行う場合は、最も簡単な解決手段はデータベースからユーザーをm再取得することです。実装例を以下に示します。
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from myapp.models import BlogPost
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_blogpost")
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.get(
codename="change_blogpost",
content_type=content_type,
)
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm("myapp.change_blogpost") # False
# Request new instance of User
# Be aware that user.refresh_from_db() won't clear the cache.
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm("myapp.change_blogpost") # True
...
プロキシモデル¶
プロキシモデルは具象モデルと全く同じように動作します。権限は、プロキシモデルの独自のコンテンツタイプを使って作成されます。プロキシモデルは、サブクラスである具象モデルのパーミッションを継承しません。
class Person(models.Model):
class Meta:
permissions = [("can_eat_pizzas", "Can eat pizzas")]
class Student(Person):
class Meta:
proxy = True
permissions = [("can_deliver_pizzas", "Can deliver pizzas")]
>>> # Fetch the content type for the proxy model.
>>> content_type = ContentType.objects.get_for_model(Student, for_concrete_model=False)
>>> student_permissions = Permission.objects.filter(content_type=content_type)
>>> [p.codename for p in student_permissions]
['add_student', 'change_student', 'delete_student', 'view_student',
'can_deliver_pizzas']
>>> for permission in student_permissions:
... user.user_permissions.add(permission)
...
>>> user.has_perm("app.add_person")
False
>>> user.has_perm("app.can_eat_pizzas")
False
>>> user.has_perms(("app.add_student", "app.can_deliver_pizzas"))
True
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() 関数を使用できます。
-
login(request, user, backend=None)¶
-
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 で定義されているのと同様に)ドット付きのインポート先を示すパスの文字列でなければなりません。
ユーザーをログアウトさせる方法¶
-
logout(request)¶
-
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 が非アクティブのユーザを拒否します。
テストをパスしたログイン済みユーザのアクセスを制限する¶
特定の権限やその他のテストに基づいてアクセスを制限するには、前のセクションで説明したのと基本的に同じことを行います。
直接ビューで 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): ...
-
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()によって返されたパーミッションのリストで呼び出した結果を返します。
-
クラスベースのビューで、不正なリクエストをリダイレクトする¶
クラスベースのビュー におけるアクセス制限の取り扱いを簡単にするために、 AccessMixin を使ってアクセスが拒否されたときのビューの動作を指定できます。認証されたユーザーはHTTP 403 Forbiddenレスポンスでアクセスを拒否されます。匿名ユーザーは raise_exception 属性に応じて、ログインページにリダイレクトされるか、HTTP 403 Forbidden レスポンスが表示されます。
-
class
AccessMixin¶ -
login_url¶ get_login_url()のデフォルトの戻り値。デフォルトはNoneで、この場合get_login_url()はsettings.LOGIN_URLにフォールバックします。
-
permission_denied_message¶ get_permission_denied_message()のデフォルトの戻り値。デフォルトは空文字列です。
-
redirect_field_name¶ get_redirect_field_name()のデフォルトの戻り値。デフォルトは"next"です。
-
raise_exception¶ この属性が
Trueに設定されている場合、条件が満たされないとPermissionDenied例外が発生します。False(デフォルト) の場合、匿名ユーザはログインページにリダイレクトされます。
-
get_login_url()¶ テストにパスしなかったユーザーがリダイレクトされる URL を返します。設定されていれば
login_urlを、設定されていなければsettings.LOGIN_URLを返します。
-
get_permission_denied_message()¶ raise_exceptionがTrueの場合、このメソッドを使ってエラーハンドラに渡されるエラーメッセージを制御できます。デフォルトではpermission_denied_message属性を返します。
-
get_redirect_field_name()¶ ログインに成功した後にユーザーがリダイレクトされる URL を含むクエリパラメータの名前を返します。これを
Noneに設定すると、クエリパラメータは追加されません。デフォルトではredirect_field_name属性を返します。
-
handle_no_permission()¶ raise_exceptionの値に応じて、このメソッドはPermissionDenied例外を発生させるか、ユーザをlogin_urlにリダイレクトします。オプションとしてredirect_field_nameが指定されている場合は、それを含みます。
-
パスワード変更時にセッションを無効化する¶
AUTH_USER_MODEL が AbstractBaseUser を継承しているか、独自の get_session_auth_hash() メソッドを実装している場合、認証されたセッションにはこの関数が返すハッシュが含まれます。AbstractBaseUser の場合、これはパスワードフィールドの HMAC です。Django は各リクエストのセッションのハッシュが、リクエスト中に計算されたハッ シュと一致することを確認します。これにより、ユーザはパスワードを変更することで、全てのセッションをログアウトできます。
Django に含まれるデフォルトのパスワード変更ビュー、 PasswordChangeView と、 django.contrib.auth admin の user_change_password ビューは、ユーザが自分のパスワードを変更してもログアウトしないように、新しいパスワードハッシュでセッションを更新します。カスタムのパスワード変更ビューがあり、同様の動作をさせたい場合は update_session_auth_hash() 関数を使用してください。
-
update_session_auth_hash(request, user)¶
-
aupdate_session_auth_hash(request, user)¶ 非同期バージョン:
aupdate_session_auth_hash()この関数は現在のリクエストと、新しいセッションハッシュの元になる 更新されたユーザオブジェクトを受け取り、セッションハッシュを適切に更新します。また、盗まれたセッションクッキーが無効になるようにセッションキーをローテートします。
使用例:
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: ...
Changed in Django 5.0:aupdate_session_auth_hash()関数が追加されました。
注釈
get_session_auth_hash() は SECRET_KEY に基づいているので、サイトを更新して新しいシークレットを使用する場合、既存のセッションが無効にならないようにシークレットキーの値をローテーションする必要があります。詳細は SECRET_KEY_FALLBACKS を参照してください。
認証ビュー¶
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_pageURL を上書きします。
-
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_urlURL セットが指定されていないときに呼び出されます。注釈
提供されたメールアドレスがシステムにない、ユーザーが非アクティブである、もしくは無効なパスワードの場合でも、ユーザはこのページにリダイレクトされますが、メールは送信されません。
属性:
-
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¶ ユーザのパスワードを変更するために admin インターフェイス内で使われるフォームです。
第 1 引数として
userを取ります。
-
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
PasswordChangeForm¶ ユーザがパスワードを変更できるようにするフォームです。
-
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
SetPasswordForm¶ 古いパスワードを入力しないでパスワードを変更できるようにするフォームです。
-
class
UserChangeForm¶ ユーザの情報とパーミッションを変更するために admin インターフェイスで使われるフォームです。
-
class
BaseUserCreationForm¶ - New in Django 4.2.
新しいユーザを作成するための
ModelFormです。これは、ユーザ作成フォームをカスタマイズする必要がある場合に推奨される基本クラスです。username(ユーザモデルより)、password1、password2という3つのフィールドがあります。password1とpassword2が一致するか確認し、validate_password()を使ってパスワードを検証します。そして、set_password()を使ってユーザのパスワードをセットします。
-
class
UserCreationForm¶ BaseUserCreationFormを継承しています。似たようなユーザ名による混乱を防ぐために、このフォームでは大文字小文字が異なるだけのユーザ名は使用できません。Changed in Django 4.2:古いバージョンでは、
UserCreationFormはカスタムユーザモデルの多対多のフォームフィールドを保存していませんでした。古いバージョンでは、大文字と小文字が異なるだけのユーザー名が許可されています。
テンプレート内の認証データ¶
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 でのユーザー編集のログも保管および表示されます。
ユーザを作成する¶
admin のメインインデックスページの "Auth" セクションに "Users" へのリンクがあります。"Add user" ページは通常の admin ページとは異なり、他のユーザーのフィールドを編集する際に、ユーザ名とパスワードを選択する必要があります。
また、Django の admin サイトを使用してユーザアカウントを作成できるようにするには、ユーザを追加 および 変更する権限をユーザに与える必要があります (つまり "Add user" と "Change user" パーミッション)。あるアカウントにユーザの追加権限のみが与えられ変更権限がない場合、そのアカウントはユーザを追加できません。なぜなら、追加権限によってスーパーユーザを作成することができ、そのスーパーユーザを使って他のユーザーを変更することができてしまうからです。 そのため、Django はちょっとしたセキュリティ対策として、追加と変更の 両方 の権限を必要とするのです。
ユーザに与えるパーミッション管理の権限については、よく考える必要があります。たとえば非スーパーユーザにユーザ編集の権限を与えてしまうと、結果的に彼らにスーパーユーザと同じ能力を与えることになります。というのも、彼らはユーザ編集の権限によってユーザのパーミッションを昇格させることができるため、彼ら自身のパーミッションも昇格させられるのです!
パスワードを変更する¶
ユーザーのパスワードは管理画面には表示されません(データベースにも保存されません)が、 パスワード保管についての詳細 は表示されます。この情報の表示には、管理者がユーザーパスワードを変更するためのパスワード変更フォームへのリンクが含まれています。