Djangoの認証システムを使用する¶
このドキュメントでは、デフォルト設定でのDjangoの認証システムの使用方法を説明します。この設定は、タスクの適切な範囲を管理することで、最も一般的なプロジェクトのニーズにかなうよう徐々に発展してきました。そして、パスワードや権限の入念な実装を持っています。デフォルトの認証システムからの変更が必要なプロジェクトのために、Djangoは認証システムの広範囲の 拡張とカスタマイズ をサポートします。
Djangoの認証は、認証機能と権限機能の両方を共に提供しています。そして、一般的に、これらの機能を合わせて認証システムと呼びます。
User
オブジェクト¶
User
オブジェクトは、認証システムの中核です。一般的に、このオブジェクトはあなたのサイトに関係する人々を表し、アクセスを制限すること、ユーザ情報を登録すること、コンテンツを作成者と関連付けることを可能にする際などに利用されます。
Djangoの認証フレームワークにはUserクラスという、ただひとつのクラスのみが存在します。すなわち、 'superusers'
または admin 'staff'
ユーザは、Userオブジェクトと異なるクラスではなく、特別な属性セットを持ったUserオブジェクトなのです。
デフォルトのユーザの主要な属性は次のとおりです。
仕様については full API documentation
を参照してください。 次のドキュメントは、よりタスク指向の形式となっています。
ユーザを作成する¶
ユーザを作成するための最も直接的な方法は、組み込まれている 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をインストールしている場合は、 インタラクティブにユーザを作成する こともできます。
スーパーユーザを作成する¶
Create superusers using the createsuperuser
command:
$ python manage.py createsuperuser --username=joe --email=joe@example.com
パスワードを入力するように促されます。入力後、ただちにユーザが作成されます。 --username
または --email
オプションを使用しなければ、これらの値を入力するように促されます。
パスワードを変更する¶
Djangoはユーザモデルに未加工の(はっきりとしたテキストの)パスワードは保存せず、ハッシュ値でのみ保存します( 詳細は、 パスワードは管理方法に関するドキュメント を参照してください)。これにより、パスワード属性を使用されません。これが、ユーザを作成する際にヘルパー関数を使用する理由です。
ユーザのパスワードを変更するには、いくつかのオプションがあります。
manage.py changepassword *username*
offers a method
of changing a user’s password from the command line. It prompts you to
change the password of a given user which you must enter twice. If
they both match, the new password will be changed immediately. If you
do not supply a user, the command will attempt to change the password
whose username matches the current system user.
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はユーザ自身のパスワードを変更するための ビュー と フォーム を提供します。
ユーザーのパスワード変更を行う事とそのユーザーのセッションは全てログアウトされます。詳細は Session invalidation on password change を参照してください。
ユーザを認証する¶
-
authenticate
(**credentials)[ソース]¶ 認証情報のセットを検証するには
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
注釈
これは、一連の資格情報を認証するための低レベルの方法です。例えば、
RemoteUserMiddleware
でこの方法使われます。独自の認証システムを書いていない限り、あなたはおそらくこれを使用しません。あなたはログインユーザへのアクセスを制限する方法を探しているというならば、login_required()
デコレータを参照してください。
権限と認可¶
Djangoにはシンプルな権限システムが付属しています。これにより、特定のユーザーおよびユーザのグループに権限を割り当てるための方法を提供します。
これは、Djangoのadminサイトでも使われていますが、独自のコード内でも自由に使えます。
Djangoのadminサイトは、次のように権限を使用します:
“追加”フォームのビューにアクセスし、オブジェクトの追加をすることは、そのオブジェクトの型への”追加”権限を持つユーザに限定されています。
変更リストを表示し、”変更”フォームを表示し、オブジェクトを変更することは、そのオブジェクトの型への”変更”権限を持つユーザーに限定されています。
オブジェクトを削除することは、そのオブジェクトの型への”削除”権限を持つユーザに限定されています。
権限はオブジェクトの型に対してだけでなく、特定のオブジェクトのインスタンスに対しても同様に割り当てる事ができます。ModelAdmin
クラスで提供されている has_add_permission()
、has_change_permission()
および has_delete_permission()
のメソッドを利用する事で、同じ型であっても異なったオブジェクトのインスタンスに対し付与する権限のカスタマイズが可能となります。
User
オブジェクトは 2 つの多対多のフィールド、groups
および user_permissions
を持っています。他の Django におけるモデル で行えるのと同様に User
オブジェクトは関連を持っているオブジェクトにアクセスできます:
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()
デフォルトの権限¶
django.contrib.auth
が INSTALLED_APPS
内に設定されている場合、追加、変更および削除の 3 つの権限が定義され、これらはインストールされたアプリケーション単体に定義されている Django モデルそれぞれに対して作成されます。
これらの権限は 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')
Permission
モデルに対して直接アクセスする事はほぼ有りません。
グループ¶
django.contrib.auth.models.Group
モデルはユーザーを分類する一般的な方法で、対象となるユーザーに権限や、何らかの分類名を付けることが可能となります。個々のユーザーは複数のグループに属する事ができます。
グループに属するユーザーは、そのグループに対して許可されている権限を自動的に持つ事になります。例えば、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
に割り当てられます。
権限のキャッシュ¶
ModelBackend
はユーザーオブジェクトが権限の確認のため最初に要求した情報をキャッシュします。この仕組みはリクエスト-レスポンスのサイクルの中では(例えば管理機能によって)通常の場合、権限が付与されてから直ちに権限の確認が生じる事が無いため大抵の場合問題がありません。もし権限を付与した後直ちに権限の確認を行う場合、テストあるいは認証をビューで例示する場合等、最も簡単な解決手段はデータベースから再度ユーザーの情報を取得する事です。以下は実装例です:
from django.contrib.auth.models import Permission, User
from django.shortcuts import get_object_or_404
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_bar')
permission = Permission.objects.get(codename='change_bar')
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('myapp.change_bar') # 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_bar') # True
...
Web のリクエストにおける認証¶
Django は リクエストオブジェクト
に対して認証システムを接続させるのに セッション とミドルウェアを利用します。
それらは現在のユーザーを示す request.user
属性を付与します。もしユーザーが現在ログインしていない場合、この属性には AnonymousUser
のインスタンスが、ログインしている場合は User
のインスタンスがセットされます。
この二者は is_authenticated
を用いて次のように識別する事ができます:
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
ユーザーをログインさせるには¶
現在のセッションにおいて認証を有効としたいユーザーがいる場合 - login()
関数によってそれを行う事ができます。
-
login
(request, user, backend=None)[ソース]¶ あるユーザーをログインさせる場合は、
login()
を利用してください。この関数はHttpRequest
オブジェクトとUser
オブジェクトを受け取ります。login()
は Django のセッションフレームワークを利用して、ユーザーのセッション中での ID を保持します。匿名ユーザーとしてのセッション中にセットされたデータが、ログイン後も継続して利用できる事に注意してください。
以下の例では
authenticate()
およびlogin()
をどのように用いるかを示します:from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(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 1.10:従来のバージョンでは、手動でユーザーをログインさせる場合、
login()
を呼び出す前にauthenticate()
を用いたユーザーの認証に 成功していなければ なりませんでした。現在のバージョンでは引数backend
を用いて認証バックエンドを指定する事ができます。
認証バックエンドの選択¶
ユーザーがログインする際、そのユーザーの ID と認証時に用いた認証バックエンドはセッション中保持されます。その仕組みによって、ユーザーの詳細情報を取得するリクエストが発生した場合に同じ 認証バックエンド を利用できます。セッション中に保持される認証バックエンドは下記の手順を経て選択されます:
省略可能な
backend
引数が与えられている場合は利用します。存在すれば属性
user.backend
の値を利用する。authenticate()
は返すユーザーオブジェクトに属性値user.backend
を付与するので、authenticate()
とlogin()
とで連携を図ることができる。ただ一つだけ設定が存在すれば
AUTHENTICATION_BACKENDS
のbackend
を利用する。いずれにも該当しなかった場合、例外が送出される。
1 もしくは 2 においては、引数 backend
あるいは属性値 user.backend
は(AUTHENTICATION_BACKENDS
で定義されているのと同様に)ドット付きのインポート先を示すパスの文字列でなければなりません。
ユーザーをログアウトさせるには¶
-
logout
(request)[ソース]¶ 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()
を呼びだすと、現在処理しているリクエストに対応したセッション情報は完全に破棄されます。その時点までに存在している全てのデータが削除されます。これは別の人物が同じ Web ブラウザを利用してログインし、前のユーザーのセッションにアクセスして使用してしまう事態を防ぐためです。ログアウトした直後から利用できる何らかの情報をセッションに保存したい場合は、django.contrib.auth.logout()
を呼び出した後に処理してください。
ログインしているユーザーにアクセスを制限する¶
原理的な方法¶
ページに対するアクセスを制限する原理的な方法は 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('%s?next=%s' % (settings.LOGIN_URL, 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 url(r'^accounts/login/$', auth_views.login),
settings.LOGIN_URL
はまたビュー関数名と 命名された URL パターン を受け付けます。この仕組みによって設定を更新することなく URLconf 内のログイン用ビューを再配置する事ができます。
注釈
login_required
デコレータはユーザーのフラグ is_active
をチェックしませんが、デフォルトの AUTHENTICATION_BACKENDS
はアクティブでないユーザを拒否します。
参考
もし Django の管理画面にカスタマイズしたビューを実装している(あるいはビルトインのビューが利用しているのと同じ認証チェックが必要である)場合は、django.contrib.admin.views.decorators.staff_member_required()
デコレータが login_required()
の代替として有用であるはずです。
The LoginRequired
mixin¶
When using class-based views, you can
achieve the same behavior as with login_required
by using the
LoginRequiredMixin
. This mixin should be at the leftmost position in the
inheritance list.
-
class
LoginRequiredMixin
¶ - New in Django 1.9.
If a view is using this mixin, all requests by non-authenticated users will be redirected to the login page or shown an HTTP 403 Forbidden error, depending on the
raise_exception
parameter.You can set any of the parameters of
AccessMixin
to customize the handling of unauthorized users:from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): login_url = '/login/' redirect_field_name = 'redirect_to'
注釈
Just as the login_required
decorator, this mixin does NOT check the
is_active
flag on a user, but the default
AUTHENTICATION_BACKENDS
reject inactive users.
Limiting access to logged-in users that pass a test¶
To limit access based on certain permissions or some other test, you’d do essentially the same thing as described in the previous section.
The simple way is to run your test on request.user
in the view directly. For example, this view
checks to make sure the user has an email in the desired domain and if not,
redirects to the login page:
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')[ソース]¶ As a shortcut, you can use the convenient
user_passes_test
decorator which performs a redirect when the callable returnsFalse
: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()
takes a required argument: a callable that takes aUser
object and returnsTrue
if the user is allowed to view the page. Note thatuser_passes_test()
does not automatically check that theUser
is not anonymous.user_passes_test()
takes two optional arguments:login_url
- Lets you specify the URL that users who don’t pass the test will be
redirected to. It may be a login page and defaults to
settings.LOGIN_URL
if you don’t specify one. redirect_field_name
- Same as for
login_required()
. Setting it toNone
removes it from the URL, which you may want to do if you are redirecting users that don’t pass the test to a non-login page where there’s no “next page”.
For example:
@user_passes_test(email_check, login_url='/login/') def my_view(request): ...
-
class
UserPassesTestMixin
¶ - New in Django 1.9.
When using class-based views, you can use the
UserPassesTestMixin
to do this.-
test_func
()¶ You have to override the
test_func()
method of the class to provide the test that is performed. Furthermore, you can set any of the parameters ofAccessMixin
to customize the handling of unauthorized users: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
()¶ You can also override the
get_test_func()
method to have the mixin use a differently named function for its checks (instead oftest_func()
).
Stacking
UserPassesTestMixin
Due to the way
UserPassesTestMixin
is implemented, you cannot stack them in your inheritance list. The following does NOT work: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): ...
If
TestMixin1
would callsuper()
and take that result into account,TestMixin1
wouldn’t work standalone anymore. -
The permission_required
decorator¶
-
permission_required
(perm, login_url=None, raise_exception=False)[ソース]¶ It’s a relatively common task to check whether a user has a particular permission. For that reason, Django provides a shortcut for that case: the
permission_required()
decorator.:from django.contrib.auth.decorators import permission_required @permission_required('polls.can_vote') def my_view(request): ...
Just like the
has_perm()
method, permission names take the form"<app label>.<permission codename>"
(i.e.polls.can_vote
for a permission on a model in thepolls
application).The decorator may also take an iterable of permissions, in which case the user must have all of the permissions in order to access the view.
Note that
permission_required()
also takes an optionallogin_url
parameter:from django.contrib.auth.decorators import permission_required @permission_required('polls.can_vote', login_url='/loginpage/') def my_view(request): ...
As in the
login_required()
decorator,login_url
defaults tosettings.LOGIN_URL
.If the
raise_exception
parameter is given, the decorator will raisePermissionDenied
, prompting the 403 (HTTP Forbidden) view instead of redirecting to the login page.If you want to use
raise_exception
but also give your users a chance to login first, you can add thelogin_required()
decorator:from django.contrib.auth.decorators import login_required, permission_required @login_required @permission_required('polls.can_vote', raise_exception=True) def my_view(request): ...
Changed in Django 1.9:In older versions, the
permission
parameter only worked with strings, lists, and tuples instead of strings and any iterable.
The PermissionRequiredMixin
mixin¶
To apply permission checks to class-based views, you can use the PermissionRequiredMixin
:
-
class
PermissionRequiredMixin
¶ - New in Django 1.9.
This mixin, just like the
permission_required
decorator, checks whether the user accessing a view has all given permissions. You should specify the permission (or an iterable of permissions) using thepermission_required
parameter:from django.contrib.auth.mixins import PermissionRequiredMixin class MyView(PermissionRequiredMixin, View): permission_required = 'polls.can_vote' # Or multiple of permissions: permission_required = ('polls.can_open', 'polls.can_edit')
You can set any of the parameters of
AccessMixin
to customize the handling of unauthorized users.You may also override these methods:
-
get_permission_required
()¶ Returns an iterable of permission names used by the mixin. Defaults to the
permission_required
attribute, converted to a tuple if necessary.
-
has_permission
()¶ Returns a boolean denoting whether the current user has permission to execute the decorated view. By default, this returns the result of calling
has_perms()
with the list of permissions returned byget_permission_required()
.
-
Redirecting unauthorized requests in class-based views¶
To ease the handling of access restrictions in class-based views, the AccessMixin
can be used to redirect a
user to the login page or issue an HTTP 403 Forbidden response.
-
class
AccessMixin
¶ - New in Django 1.9.
-
login_url
¶ Default return value for
get_login_url()
. Defaults toNone
in which caseget_login_url()
falls back tosettings.LOGIN_URL
.
-
permission_denied_message
¶ Default return value for
get_permission_denied_message()
. Defaults to an empty string.
-
redirect_field_name
¶ Default return value for
get_redirect_field_name()
. Defaults to"next"
.
-
raise_exception
¶ If this attribute is set to
True
, aPermissionDenied
exception will be raised instead of the redirect. Defaults toFalse
.
-
get_login_url
()¶ Returns the URL that users who don’t pass the test will be redirected to. Returns
login_url
if set, orsettings.LOGIN_URL
otherwise.
-
get_permission_denied_message
()¶ When
raise_exception
isTrue
, this method can be used to control the error message passed to the error handler for display to the user. Returns thepermission_denied_message
attribute by default.
-
get_redirect_field_name
()¶ Returns the name of the query parameter that will contain the URL the user should be redirected to after a successful login. If you set this to
None
, a query parameter won’t be added. Returns theredirect_field_name
attribute by default.
-
handle_no_permission
()¶ Depending on the value of
raise_exception
, the method either raises aPermissionDenied
exception or redirects the user to thelogin_url
, optionally including theredirect_field_name
if it is set.
-
Session invalidation on password change¶
Session verification is enabled and mandatory in Django 1.10 (there’s no
way to disable it) regardless of whether or not
SessionAuthenticationMiddleware
is enabled. In older
versions, this protection only applies if
django.contrib.auth.middleware.SessionAuthenticationMiddleware
is enabled in MIDDLEWARE
.
If your AUTH_USER_MODEL
inherits from
AbstractBaseUser
or implements its own
get_session_auth_hash()
method, authenticated sessions will include the hash returned by this function.
In the AbstractBaseUser
case, this is an
HMAC of the password field. Django verifies that the hash in the session for
each request matches the one that’s computed during the request. This allows a
user to log out all of their sessions by changing their password.
The default password change views included with Django,
password_change()
and the
user_change_password
view in the django.contrib.auth
admin, update
the session with the new password hash so that a user changing their own
password won’t log themselves out. If you have a custom password change view
and wish to have similar behavior, use the update_session_auth_hash()
function. In this case, however, if a user also wants to invalidate the session
from which they’re changing their password (for example, if they believe the
session cookie on their machine was stolen), then they also need to log out
that session.
-
update_session_auth_hash
(request, user)[ソース]¶ This function takes the current request and the updated user object from which the new session hash will be derived and updates the session hash appropriately. Example usage:
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: ...
注釈
Since
get_session_auth_hash()
is based on SECRET_KEY
, updating your site to use a new secret
will invalidate all existing sessions.
Authentication Views¶
Django provides several views that you can use for handling login, logout, and password management. These make use of the stock auth forms but you can pass in your own forms as well.
Django provides no default template for the authentication views. You should create your own templates for the views you want to use. The template context is documented in each view, see All authentication views.
Using the views¶
There are different methods to implement these views in your project. The
easiest way is to include the provided URLconf in django.contrib.auth.urls
in your own URLconf, for example:
urlpatterns = [
url('^', include('django.contrib.auth.urls')),
]
This will include the following URL patterns:
^login/$ [name='login']
^logout/$ [name='logout']
^password_change/$ [name='password_change']
^password_change/done/$ [name='password_change_done']
^password_reset/$ [name='password_reset']
^password_reset/done/$ [name='password_reset_done']
^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
^reset/done/$ [name='password_reset_complete']
The views provide a URL name for easier reference. See the URL documentation for details on using named URL patterns.
If you want more control over your URLs, you can reference a specific view in your URLconf:
from django.contrib.auth import views as auth_views
urlpatterns = [
url('^change-password/$', auth_views.password_change),
]
The views have optional arguments you can use to alter the behavior of the
view. For example, if you want to change the template name a view uses, you can
provide the template_name
argument. A way to do this is to provide keyword
arguments in the URLconf, these will be passed on to the view. For example:
urlpatterns = [
url(
'^change-password/$',
auth_views.password_change,
{'template_name': 'change-password.html'}
),
]
All views return a TemplateResponse
instance, which allows you to easily customize the response data before
rendering. A way to do this is to wrap a view in your own view:
from django.contrib.auth import views
def change_password(request):
template_response = views.password_change(request)
# Do something with `template_response`
return template_response
For more details, see the TemplateResponse documentation.
All authentication views¶
This is a list with all the views django.contrib.auth
provides. For
implementation details see Using the views.
-
login
(request, template_name=`registration/login.html`, redirect_field_name='next', authentication_form=AuthenticationForm, current_app=None, extra_context=None, redirect_authenticated_user=False)¶ URL name:
login
See the URL documentation for details on using named URL patterns.
Optional arguments:
template_name
: The name of a template to display for the view used to log the user in. Defaults toregistration/login.html
.redirect_field_name
: The name of aGET
field containing the URL to redirect to after login. Defaults tonext
.authentication_form
: A callable (typically just a form class) to use for authentication. Defaults toAuthenticationForm
.current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.redirect_authenticated_user
: A boolean that controls whether or not authenticated users accessing the login page will be redirected as if they had just successfully logged in. Defaults toFalse
.警告
If you enable
redirect_authenticated_user
, other websites will be able to determine if their visitors are authenticated on your site by requesting redirect URLs to image files on your website. To avoid this “social media fingerprinting” information leakage, host all images and your favicon on a separate domain.
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.New in Django 1.10:The
redirect_authenticated_user
parameter was added.Here’s what
django.contrib.auth.views.login
does:- If called via
GET
, it displays a login form that POSTs to the same URL. More on this in a bit. - If called via
POST
with user submitted credentials, it tries to log the user in. If login is successful, the view redirects to the URL specified innext
. Ifnext
isn’t provided, it redirects tosettings.LOGIN_REDIRECT_URL
(which defaults to/accounts/profile/
). If login isn’t successful, it redisplays the login form.
It’s your responsibility to provide the html for the login template , called
registration/login.html
by default. This template gets passed four template context variables:form
: AForm
object representing theAuthenticationForm
.next
: The URL to redirect to after successful login. This may contain a query string, too.site
: The currentSite
, according to theSITE_ID
setting. If you don’t have the site framework installed, this will be set to an instance ofRequestSite
, which derives the site name and domain from the currentHttpRequest
.site_name
: An alias forsite.name
. If you don’t have the site framework installed, this will be set to the value ofrequest.META['SERVER_NAME']
. For more on sites, see The “sites” framework.
If you’d prefer not to call the template
registration/login.html
, you can pass thetemplate_name
parameter via the extra arguments to the view in your URLconf. For example, this URLconf line would usemyapp/login.html
instead:url(r'^accounts/login/$', auth_views.login, {'template_name': 'myapp/login.html'}),
You can also specify the name of the
GET
field which contains the URL to redirect to after login by passingredirect_field_name
to the view. By default, the field is callednext
.Here’s a sample
registration/login.html
template you can use as a starting point. It assumes you have abase.html
template that defines acontent
block:{% 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 setup the password_reset view in your URLconf #} <p><a href="{% url 'password_reset' %}">Lost password?</a></p> {% endblock %}
If you have customized authentication (see Customizing Authentication) you can pass a custom authentication form to the login view via the
authentication_form
parameter. This form must accept arequest
keyword argument in its__init__
method, and provide aget_user()
method which returns the authenticated user object (this method is only ever called after successful form validation).
-
logout
(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name='next', current_app=None, extra_context=None)¶ Logs a user out.
URL name:
logout
Optional arguments:
next_page
: The URL to redirect to after logout. Defaults tosettings.LOGOUT_REDIRECT_URL
if not supplied.template_name
: The full name of a template to display after logging the user out. Defaults toregistration/logged_out.html
if no argument is supplied.redirect_field_name
: The name of aGET
field containing the URL to redirect to after log out. Defaults tonext
. Overrides thenext_page
URL if the givenGET
parameter is passed.current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.Template context:
title
: The string “Logged out”, localized.site
: The currentSite
, according to theSITE_ID
setting. If you don’t have the site framework installed, this will be set to an instance ofRequestSite
, which derives the site name and domain from the currentHttpRequest
.site_name
: An alias forsite.name
. If you don’t have the site framework installed, this will be set to the value ofrequest.META['SERVER_NAME']
. For more on sites, see The “sites” framework.
-
logout_then_login
(request, login_url=None, current_app=None, extra_context=None)¶ Logs a user out, then redirects to the login page.
URL name: No default URL provided
Optional arguments:
login_url
: The URL of the login page to redirect to. Defaults tosettings.LOGIN_URL
if not supplied.current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.
-
password_change
(request, template_name='registration/password_change_form.html', post_change_redirect=None, password_change_form=PasswordChangeForm, current_app=None, extra_context=None)¶ Allows a user to change their password.
URL name:
password_change
Optional arguments:
template_name
: The full name of a template to use for displaying the password change form. Defaults toregistration/password_change_form.html
if not supplied.post_change_redirect
: The URL to redirect to after a successful password change.password_change_form
: A custom “change password” form which must accept auser
keyword argument. The form is responsible for actually changing the user’s password. Defaults toPasswordChangeForm
.current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.Template context:
form
: The password change form (seepassword_change_form
above).
-
password_change_done
(request, template_name='registration/password_change_done.html', current_app=None, extra_context=None)¶ The page shown after a user has changed their password.
URL name:
password_change_done
Optional arguments:
template_name
: The full name of a template to use. Defaults toregistration/password_change_done.html
if not supplied.current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.
-
password_reset
(request, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None, extra_email_context=None)¶ パスワードをリセットするために使われる 1 回限り有効なリンクを生成し、ユーザがパスワードをリセットできるようにします。そのリンクはユーザーが登録した E メールアドレスに送信されます。
システムに E メールアドレスが登録されていない場合、E メールは送信されませんが、ユーザはエラーメッセージを受け取りません。これは、情報が悪意を持った攻撃者に流出するのを防ぐためです。エラーメッセージを提供するように変更したいときは、
PasswordResetForm
をサブクラス化して、password_reset_form
引数を使用してください。無効なパスワード (詳しくは
set_unusable_password()
) でフラグが立てられたユーザは、パスワードリセットのリクエストができないようになっており、LDAP のような外部の認証ソースを使っているときに悪用されるのを防ぎます。アカウントの存在が漏洩しないように、ユーザーはエラーメッセージを受け取ることもメールが送信されることもありません。URL 名:
password_reset
Optional arguments:
template_name
: パスワードリセットのフォームを表示するためのテンプレート名です。指定しない場合のデフォルトはregistration/password_reset_form.html
です。email_template_name
: リセットパスワードのリンクとともに生成される E メールを生成するためのテンプレート名です。指定しない場合のデフォルトはregistration/password_reset_email.html
です。subject_template_name
: リセットパスワードのリンクとともに生成される E メールの表題に対して使われるテンプレートの名前です。指定しない場合のデフォルトはregistration/password_reset_subject.txt
です。password_reset_form
: ユーザーがパスワードをリセットするために E メールを受け取るために使われるフォームです。デフォルトはPasswordResetForm
です。token_generator
: 1 回限りのリンクをチェックするためのクラスのインスタンスです。デフォルトはdefault_token_generator
で、これはdjango.contrib.auth.tokens.PasswordResetTokenGenerator
のインスタンスです。post_reset_redirect
: パスワードリセットのリクエストが成功した後のリダイレクト先の URL です。from_email
: 検証済みの E メールアドレスです。デフォルトでは、Django はDEFAULT_FROM_EMAIL
を使います。current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.html_email_template_name
: パスワードリセットのリンクとともに送信されるtext/html
のマルチパートの E メールを生成するためのテンプレートの名前です。デフォルトでは、HTML メールは送信されません。extra_email_context
: E メールテンプレート内で使われるコンテキストデータのディクショナリです。
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.New in Django 1.9:extra_email_context
パラメータが追加されました。Template context:
form
: ユーザーのパスワードをリセットするためのフォームです (詳細は上述のpassword_reset_form
)。
E メールテンプレートのコンテキスト:
email
:user.email
の別名 (エイリアス) です。user
: 現在のUser
で、email
フォームフィールドから取得されます。アクティブなユーザ (User.is_active が True
) だけがパスワードをリセットすることができます。site_name
: An alias forsite.name
. If you don’t have the site framework installed, this will be set to the value ofrequest.META['SERVER_NAME']
. For more on sites, see The “sites” framework.domain
:site.domain
の別名 (エイリアス) です。サイトのフレームワークをインストールしていない場合、request.get_host()
の値がセットされます。protocol
: http か https です。uid
: Base 64 でエンコードされたユーザのプライマリキーです。token
: リセットリンクを検証するためのトークンです。
以下はサンプルの
registration/password_reset_email.html
(E メール本文のテンプレート)です:Someone asked for password reset for email {{ email }}. Follow the link below: {{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
表題のテンプレートにも同じテンプレートコンテキストが使われます。表題は 1 行のプレーンテキスト文字列の必要があります。
-
password_reset_done
(request, template_name='registration/password_reset_done.html', current_app=None, extra_context=None)¶ パスワードリセットのためのリンクが E メール送信された後にユーザに表示されるページです。デフォルトでは、
password_reset()
ビューに明示的にpost_reset_redirect
URL セットがない場合に呼ばれます。URL 名:
password_reset_done
注釈
提供された E メールアドレスがシステムにない、ユーザーが非アクティブである、もしくは無効なパスワードの場合でも、ユーザはこのページにリダイレクトされますが、E メールは送信されません。
Optional arguments:
template_name
: テンプレートの名前です。指定しない場合のデフォルトはregistration/password_reset_done.html
です。current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.
-
password_reset_confirm
(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None)¶ 新しいパスワードを入力するためのフォームを提供します。
URL 名:
password_reset_confirm
Optional arguments:
uidb64
: Base 64 でエンコードされたユーザの ID です。デフォルトはNone
です。token
: パスワードが有効かを確認するためのトークンです。デフォルトはNone
です。template_name
: パスワード確認のビューをを表示するためのテンプレートの名前です。デフォルト値はregistration/password_reset_confirm.html
です。token_generator
: パスワードをチェックするためのクラスのインスタンスです。デフォルトはdefault_token_generator``で、これは ``django.contrib.auth.tokens.PasswordResetTokenGenerator
のインスタンスです。set_password_form
: パスワードをセットするために使われるフォームです。デフォルトはSetPasswordForm
です。post_reset_redirect
: パスワードリセットが完了したときのリダイレクト先の URLです。デフォルトはNone
です。current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.
Template context:
form
: 新しいユーザーのパスワードをセットするためのフォーム (詳しくは上述のset_password_form
) です。validlink
: 真偽値で、リンク (uidb64
とtoken
の組み合わせ) が有効か、まだ使われていない場合に True となります。
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.
-
password_reset_complete
(request, template_name='registration/password_reset_complete.html', current_app=None, extra_context=None)¶ パスワードの変更が成功したことをユーザに知らせるためのビューを提供します。
URL 名:
password_reset_complete
Optional arguments:
template_name
: ビューを表示するためのテンプレートの名前です。デフォルトはregistration/password_reset_complete.html
です。current_app
: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.extra_context
: A dictionary of context data that will be added to the default context data passed to the template.
バージョン 1.9 で撤廃: The
current_app
parameter is deprecated and will be removed in Django 2.0. Callers should setrequest.current_app
instead.
ヘルパー関数¶
-
redirect_to_login
(next, login_url=None, redirect_field_name='next')¶ ログインページにリダイレクトし、ログイン成功後にもう 1 つの URL に戻ります。
必須の引数:
next
: ログイン成功後のリダイレクト先の URL です。
Optional arguments:
login_url
: The URL of the login page to redirect to. Defaults tosettings.LOGIN_URL
if not supplied.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 forms.ValidationError( _("This account is inactive."), code='inactive', ) if user.username.startswith('b'): raise forms.ValidationError( _("Sorry, accounts starting with 'b' aren't welcome here."), code='no_b_users', )
-
-
class
PasswordChangeForm
¶ ユーザがパスワードを変更できるようにするフォームです。
-
class
PasswordResetForm
¶ ユーザのパスワードリセットするための 1 回限りのリンクを生成して E メール送信するためのフォームです。
-
send_email
(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)¶ 引数を使って
EmailMultiAlternatives
を送信します。オーバーライドして、どのように E メールが送信されるかカスタマイズできます。パラメータ: - subject_template_name – 表題用のテンプレートです。
- email_template_name – E メール本文用のテンプレートです。
- context –
subject_template
、email_template
、html_email_template
(None
ではない場合のみ) に渡されるコンテキストです。 - from_email – 送信者の E メールです。
- to_email – リクエストしてきたユーザの E メールです。
- html_email_template_name – HTML 本文用のテンプレートです; デフォルトは
None
で、この場合プレーンテキストの E メールが送信されます。
デフォルトでは、
save()
はcontext
に 変数を格納します。この変数はpassword_reset()
が E メールのコンテキストに渡す変数と同じです。
-
-
class
SetPasswordForm
¶ 古いパスワードを入力しないでパスワードを変更できるようにするフォームです。
-
class
UserChangeForm
¶ ユーザの情報とパーミッションを変更するために admin インターフェイスで使われるフォームです。
-
class
UserCreationForm
¶ 新しいユーザを作成するための
ModelForm
です。3 つのフィールドがあります:
username
(ユーザモデルより)、password1
、password2``です。``password1
とpassword2
が一致するか確認し、validate_password()
を使ってパスワードを検証します。そして、set_password()
を使ってユーザのパスワードをセットします。
テンプレート内の認証データ¶
RequestContext
を使うと、現在ログインしているユーザとパーミッションを template context 内で使えるようにできます。
技術的には
技術的には、これらの変数は RequestContext
を使い、'django.contrib.auth.context_processors.auth'
コンテキストプロセッサを有効にしたときのみ使うことができます。これは、デフォルトで生成される設定ファイル内にあります。より詳しくは RequestContext docs を参照してください。
ユーザ¶
テンプレート 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
アプリケーションにおいて何かしらのパーミッションを有する場合、True
を返します:
{{ perms.foo }}
2 段階の属性のルックアップは User.has_perm
の代替表現です。以下の例は、ログイン中のユーザがユーザがパーミッション foo.can_vote
を有する場合に True
を表示します:
{{ perms.foo.can_vote }}
したがって、テンプレート内の {% if %}
ステートメントでパーミッションをチェックするには、以下のようにします:
{% if perms.foo %}
<p>You have permission to do something in the foo app.</p>
{% if perms.foo.can_vote %}
<p>You can vote!</p>
{% endif %}
{% if perms.foo.can_drive %}
<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.can_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 はちょっとしたセキュリティ対策として、追加と変更の 両方 の権限を必要とするのです。
ユーザに与えるパーミッション管理の権限については、よく考える必要があります。たとえば非スーパーユーザにユーザ編集の権限を与えてしまうと、結果的に彼らにスーパーユーザと同じ能力を与えることになります。というのも、彼らはユーザ編集の権限によってユーザのパーミッションを昇格させることができるため、彼ら自身のパーミッションも昇格させられるのです!
パスワードを変更する¶
User passwords are not displayed in the admin (nor stored in the database), but the password storage details are displayed. Included in the display of this information is a link to a password change form that allows admins to change user passwords.