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() を利用してください。このメソッドは認証情報をキーワード引数として受け取ります。検証する対象はデフォルトでは usernamepassword であり、その組み合わせを個々の 認証バックエンド に対して問い合わせ、認証バックエンドで認証情報が有効とされれば 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_APPSdjango.contrib.auth を追加後初めての migrate を実行した場合は、新たにインストールされるモデルに対してと同様、それまでに作成されたモデルに対してもデフォルトの権限が作成されます。以後 manage.py migrate (この権限を作成する関数は post_migrate シグナルに接続されています)を実行する度作成されるモデルに対してデフォルトの権限が作成されます。

app_labelfoo のアプリケーションと、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.
    ...
Changed in Django 5.0:

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 と認証に使用したバックエンドは、ユーザーのセッション内に保存されます。これにより、同じ 認証バックエンド が今後のリクエストでユーザーの詳細情報を取得できるようになります。セッション内に保存される認証バックエンドは、以下のように選択されます。

  1. オプションの引数 backend が与えられている場合は、その値を利用する。
  2. 存在すれば属性 user.backend の値を利用する。authenticate() は返すユーザーオブジェクトに属性値 user.backend を設定するので、これにより、authenticate()login() をペアリングできます。
  3. AUTHENTICATION_BACKENDS に設定が1つだけあれば、その backend を利用する。
  4. いずれにも該当しなかった場合、例外が送出される。

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): ...

もし TestMixin1super() を呼び出して、その結果を考慮すると、 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): ...

また、LoginViewredirect_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_exceptionTrue の場合、このメソッドを使ってエラーハンドラに渡されるエラーメッセージを制御できます。デフォルトでは 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_MODELAbstractBaseUser を継承しているか、独自の 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_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_activeTrue であること)。
  • 要求されたユーザが使用可能なパスワードを持っていること。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_loginTrue の場合にユーザーを認証する際に使用する認証バックエンドへのドット区切りパス。これは AUTHENTICATION_BACKENDS を複数設定している場合にのみ必要です。デフォルトは None です。

form_class

パスワードを設定するためのフォーム。デフォルトは SetPasswordForm です。

success_url

パスワードリセット完了後にリダイレクトする URL。デフォルトは 'password_reset_complete' です。

extra_context

テンプレートに渡されるデフォルトコンテキストデータに追加されるコンテキストデータの辞書。

reset_url_token

パスワードリセットURLのコンポーネントとして表示されるトークンパラメータ。デフォルトは 'set-password' です。

テンプレート コンテキスト:

  • form: 新しいユーザーのパスワードを設定するフォーム (上記の form_class を参照)。
  • validlink: 真偽値で、リンク (uidb64token の組み合わせ) が有効か、まだ使われていない場合に True となります。
class PasswordResetCompleteView

URL 名: password_reset_complete

パスワードの変更が成功したことをユーザに知らせるためのビューを提供します。

属性:

template_name

ビューを表示するためのテンプレートのフルネーム。デフォルトは registration/password_reset_complete.html です。

extra_context

テンプレートに渡されるデフォルトコンテキストデータに追加されるコンテキストデータの辞書。

ヘルパー関数

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)

デフォルトでは、AuthenticationFormis_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_templateemail_templatehtml_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 (ユーザモデルより)、password1password2 という3つのフィールドがあります。password1password2 が一致するか確認し、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.admindjango.contrib.auth の両方をインストールしていれば、admin でユーザ、グループおよびパーミッションを見たり管理することが簡単にできます。ユーザは通常の Django モデルと同じく作成や削除ができます。グループも作成することができ、パーミッションはユーザやグループにアサインできます。admin でのユーザー編集のログも保管および表示されます。

ユーザを作成する

admin のメインインデックスページの "Auth" セクションに "Users" へのリンクがあります。"Add user" ページは通常の admin ページとは異なり、他のユーザーのフィールドを編集する際に、ユーザ名とパスワードを選択する必要があります。

また、Django の admin サイトを使用してユーザアカウントを作成できるようにするには、ユーザを追加 および 変更する権限をユーザに与える必要があります (つまり "Add user" と "Change user" パーミッション)。あるアカウントにユーザの追加権限のみが与えられ変更権限がない場合、そのアカウントはユーザを追加できません。なぜなら、追加権限によってスーパーユーザを作成することができ、そのスーパーユーザを使って他のユーザーを変更することができてしまうからです。 そのため、Django はちょっとしたセキュリティ対策として、追加と変更の 両方 の権限を必要とするのです。

ユーザに与えるパーミッション管理の権限については、よく考える必要があります。たとえば非スーパーユーザにユーザ編集の権限を与えてしまうと、結果的に彼らにスーパーユーザと同じ能力を与えることになります。というのも、彼らはユーザ編集の権限によってユーザのパーミッションを昇格させることができるため、彼ら自身のパーミッションも昇格させられるのです!

パスワードを変更する

ユーザーのパスワードは管理画面には表示されません(データベースにも保存されません)が、 パスワード保管についての詳細 は表示されます。この情報の表示には、管理者がユーザーパスワードを変更するためのパスワード変更フォームへのリンクが含まれています。

Back to Top