revision-up-to: | 17812 (1.4) |
---|
Django にはユーザ認証システムがついてきます。 Django のユーザ認証システムは、 ユーザアカウント、グループ、パーミッションとクッキーベースのユーザセッショ ンを扱えます。このドキュメントでは、ユーザ認証の仕組みについて説明します。
認証システムは以下の要素から成り立っています:
認証のサポートは Django アプリケーションとして django.contrib.auth
にバ
ンドルされています。インストールするには、以下のようにします:
INSTALLED_APPS
設定に 'django.contrib.auth'
と、
'django.contrib.contenttypes'
を加えます。
(django.contrib.auth
モジュールのモデル
Permission
は
django.contrib.contenttypes
に依存します)manage.py syncdb
を実行します。django-admin.py startproject
が生成するデフォルトの
settings.py
ファイルの INSTALLED_APPS
には、簡便のため
'django.contrib.auth'
が最初から入っています。この場合は、単に
manage.py syncdb
するだけでかまいません。
このコマンドはその都度必要なものだけをインストールするので、
何度実行してもかまいません。
syncdb
コマンドは必要なデータベーステーブルを作成し、インストー
ル済みのアプリケーションで必要な全てのパーミッションオブジェクトを作成しま
す。また、最初に実行したときには、ユーザにスーパユーザアカウントを作成する
よう促します。
これだけで、認証サポートを使えるようになります。
models.
User
¶models.
User
User
オブジェクトには以下のフィー
ルドがあります:
username
¶必須です。30 文字以下の文字列で、英数字 (アルファベット、数字、アン ダースコア) だけを使えます。
@
, +
, .
and -
等の文字列を
含めることが出来ます。first_name
¶オプションです。30 文字以下です。オプションです。30 文字以下です。
last_name
¶オプションです。 30 文字以下です。
email
¶オプションです。 Email アドレスです。
password
¶必須です。パスワードのメタデータであるハッシュ値です (Django では生 のパスワードを保存しません)。生のパスワードは任意の長さでよく、どん な文字が入っていても構いません。詳しくは以下の「パスワード」の節を 参照して下さい。
is_staff
¶Bool 値です。この値が真なら、ユーザは admin サイトにアクセスできま す。
is_active
¶Bool 値です。この値が真なら、このアカウントを使ってログインできます。
アカウントを削除する代わりに、この値を False
に設定してください。
もしアプリケーションが外部キーをユーザに対して持っていたとしても、
この方法なら破綻しないのでおすすめです。
ユーザがログインできるかどうかをコントロールする必要性がない場合でも
認証バックエンドが is_active
フラッグをチェックする必要がない時
であっても、もしログインできるかどうかを is_active
を False
にしたくない場合でも、ログインビューの中ではあなた次第です。
しかしながら、 login()
によって使わ
れる AuthenticationForm
ビューは
does このチェックを実行します。has_perm()
のよう
な権限を確かめるメソッドのように、そして Django アドミンでの認証と
同じように。これらのような関数/メソッドはアクティブでないユーザに
対して、 False
を返します.
is_superuser
¶Bool 値です。この値が真なら、ユーザは明示的な指定がなくても全てのパー ミッションを得ます。
last_login
¶ユーザが最後にログインした時刻を表す datetime オブジェクトです。デ フォルトではログイン時現在の日付/時刻になります。
date_joined
¶アカウントの作成された時刻を表す datetime オブジェクトです。デフォ ルトではアカウント作成時現在の日付/時刻になります。
models.
User
User
オブジェクトには groups
と user_permissions
という二つの多対多のフィールドがあります。この
関係性のために、 User
オブジェクト
は他の Django モデル と同じようにして、関連づ
けされたオブジェクトにアクセスできます:
myuser.groups = [group_list]
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions = [permission_list]
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()
自動的に生成されるこれらの API に加え、
User
オブジェクトには以下のカス
タムメソッドがあります:
is_anonymous
()¶常に False
を返します。
User
オブジェクトを
AnonymousUser
オブジェクトと
区別する手段の一つです。 通常は、
is_authenticated()
メソッ
ドを使うようにしてください。
is_authenticated
()¶常に True
を返します。ユーザを認証済みかどうかを調べる一つの方
法です。このメソッドの戻り値は、ユーザが正しいパーミッションを持っ
ているか、あるいはアクティブなユーザであるかどうかに関係なく、ユー
ザが正しいユーザ名とパスワードを入力したことだけを示します。
get_full_name
()¶first_name
と
last_name
をスペースでつな
げた文字列を返します。
check_password
(raw_password)¶渡された文字列がこのユーザの正しい文字列ならば True
を返します。
(このメソッドは比較時にパスワードのハッシュ処理を行います)
set_unusable_password
()¶ユーザにパスワード未設定のマークをつけます。パスワード未設定の状態
は、パスワードが空の文字列である状態と区別されます。パスワード未設
定状態のユーザに対して
check_password()
を呼び出
すと、決して True
を返しません。このメソッドは
User
オブジェクトを直接保存し
ません。
この機能は、 LDAP ディレクトリのような外部の認証ソースを使ってアプ リケーションの認証を行いたい場合に必要です。
has_usable_password
()¶ユーザに対して
set_unusable_password()
を
呼び出し、パスワードが未設定状態であれば False
を返します。
get_group_permissions
(obj=None)¶ユーザが自分の属するグループから得ているパーミッションを表す文字列 からなるリストを返します。
リリースノートを参照してください
もし obj
が引数に渡されていれば、その種類のオブジェクトへ対する、
属するグループから得ているパーミッションしか返しません。
get_all_permissions
(obj=None)¶ユーザ自身のもつパーミッションと、ユーザの属するグループのパーミッ ションの両方からなるリストを返します。
リリースノートを参照してください
もし、 obj
が引数に渡されていれば、その特有のオブジェクトに
対するユーザのパーミッションを返します。
has_perm
(perm, obj=None)¶ユーザが特定のパーミッションを持っている場合に True
を返します。
パーミッション名 perm は
"<application name>.<lowercased model name>"
のような形式で表し
ます。ユーザがアクティブでない場合、このメソッドは常に False
を
返します。
リリースノートを参照してください
もし obj
が引数に渡されていれば、このメソッドはモデルに対する
パーミッションをチェックせず、引数のオブジェクトに対するものを
チェックしようとします。
has_perms
(perm_list, obj=None)¶ユーザが perm_list 内のパーミッションのいずれかを持っている場合に
True
を返します。各々のパーミッション名は
"<app label>.<permission codename>"
のような形式で表します。
ユーザがアクティブでない場合、このメソッドは常に False
を
返します。
リリースノートを参照してください
もし obj
が引数で渡されていれば、このメソッドはモデルに対する
権限ではなく、引数のオブジェクトに対するものを調べます。
has_module_perms
(package_name)¶ユーザが指定した名前のパッケージ (アプリケーション) の何らかのパー
ミッションを持っていれば True
を返します。ユーザがアクティブで
ない場合、このメソッドは常に False
を返します。
email_user
(subject, message, from_email=None)¶ユーザにメールを送信します。 from_email
が None
の場合、
Django は DEFAULT_FROM_EMAIL
設定を使います。
get_profile
()¶ユーザのサイト固有のプロファイル (site-specific profile) を返します。
プロファイルを使えないサイトでは
django.contrib.auth.models.SiteProfileNotAvailable
を送出し
ます。もしくはユーザがプロファイルを持っていなければ
django.core.exceptions.ObjectDoesNotExtis
を送出します。
サイト固有のユーザプロファイルを定義するには、後述の
追加のユーザ情報の保存 を参照して下さい。
models.
UserManager
¶User
モデルには、以下のヘルパ関数
を備えたマネジャがあります。
create_user
(username, email=None, password=None)¶email
パラメータはオプションになりました。username パラメ
ータは、空のものと有効でない値が出た時の ValueError
を上げるものをチェックするのに使われています。ユーザを生成して保存し、生成された
User
を返します。
username
,
email
は、自動的に小文字に変更され、
password
は指定した値にな
り、 is_active
は True
に設定されます。
パスワードを指定しなかった場合、
set_unusable_password()
を
呼び出します。
使い方は ユーザの作成 を参照してください。
make_random_password
(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')¶指定した長さのランダムなパスワードを生成して返します。パスワードに
使える文字は文字列で指定します。 allowed_chars
のデフォルト値は、
ユーザが見間違いやすい以下の文字を除いてあります:
i
, l
, I
, and 1
(lowercase letter i, lowercase
letter L, uppercase letter i, and the number one)o
, O
, and 0
(uppercase letter o, lowercase letter o,
and zero)ユーザを作成する一番基本的な方法は、オブジェクトマネージャの
create_user()
ヘルパー関数を
使う方法です:
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
>>>
# この操作で、User オブジェクト user を保存できるようになります。
# 他のフィールドを変更したければ、属性を変更します。
>>> user.is_staff = True
>>> user.save()
Django のアドミンサイトを使用するユーザを作ることも出来ます。アドミンサイトの
URL を /admin/
にひも付けると思います、 “Add user” ページは
/admin/auth/user/add/
にあります。また、アドミンのメインページ(インデ
ックスページ)の “Auth” セクションの “Users” へのリンクでも確認できます。
“Add user” 管理ページは、通常の管理ページ(アドミン)とはユーザネームと
パスワードを、残りのフィールドを変更する前に埋めなくてはならない点で異なって
います。
また、 note: もし、自身のユーザアカウントを Django のアドミンサイトを使える ようにしたいのならば、パーミッションを2つ与える必要があり、それぞれ ユーザを加える権限 と ユーザを変更する権限です。(すなわち、 “Add user” と “Change user” の権限です。)もし、あなたのアカウントが 「ユーザを加える権限」は持っていても、「ユーザを変更する権限」を持っていない 場合、ユーザを加えることはできません。なぜか? それは、ユーザを加える権限を 有しているということは、スーパユーザを作る権限を有しているということで、 スーパーユーザは同様に、他のユーザを変えることができます。だから、 Django はそれに加えてユーザ変更の権限も、セキュリティ対策として 必要としているのです。
manage.py changepassword
コマンドが追加されました。manage.py changepassword *username*
はコマンドラインからユーザのパスワードを変更する手続きを提供していま
す。パスワードを変更するには、二度指定したユーザの変更後のパスワード
を入力しなくてはいけません。二つがマッチすると、ただちにパスワードが
変更されます。ユーザを渡さないと、コマンドは最新のユーザのパスワード
を変更しようとします。
パスワードの変更には
set_password()
を使います:
.. code-block:: python
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username__exact='john')
>>> u.set_password('new password')
>>> u.save()
特別な意図のない限り、 password
属性を直接設定しないでください。これについては次節で説明します。
User
オブジェクトの
password
フィールドは、以下の形式:
algorithm$hash
すなわちストレージアルゴリズム(storage algorithm)と、ハッシュソルト (salt)、
そしてハッシュ値(hash) はドル記号 ("$"
) で分割した文字列形式をとります。
アルゴリズムはいくつかのハッシュ化または Django で使えるパスワードの
ストレージ方式のうちの一つです。下を見てください。ハッシュ値はハッシュ関数の
結果であります。
通常では、 Django は PBKDF2 アルゴリズムをSHA256ハッシュ関数で暗号化します。 パスワードのストレッチ機構は NIST によって勧告されています。これはほとんどの ユーザにとっては満足できるものでしょう。高い安全性で、パスワードを破るには 莫大な計算量を必要とします。
しかしながら必要に応じて、他のアルゴリズムを選択することもあるでしょう、また 必要なセキュリティの度合いに応じてカスタムアルゴリズムを使用する必要もあるこ とでしょう。繰り返すと、ほとんどのユーザはそれを必要とはしていません。もし、 必要性が確かではないなら、それは必要なことではないでしょう。もし、あなたが そうしたいのならば読み進めてください。
Django では PASSWORD_HASHERS
の設定でアルゴリズムを選択することが
できます。これは Django で使用するハッシュ化のアルゴリズムクラス群のリストです、
リストの最初の項目(すなわち settings.PASSWORD_HASHERS[0]
)はパスワードを
保存するために使われます。そして、他の項目は有効となったハッシュで実在する
パスワードをチェックするために使われます。つまり、もし違うアルゴリズムを使用
したくなったときに、 PASSWORD_HASHERS
を修正する必要があり、
リストの先頭に好きなアルゴリズムを組み込んでください。
通常 PASSWORD_HASHERS
は
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher',
'django.contrib.auth.hashers.CryptPasswordHasher',
)
これは、 Django は PBKDF2 を全てのパスワードの保存時に使おうとする ということです。でも、保存されたパスワードをチェックする際には、 PBKDF2SHA1, bcrypt, SHA1, その他を用います。次以降のセクションでは 高度なユーザのために、設定を変更する一般的な二つの方法を紹介します。
Bcrypt は一般的なパスワードの保存アルゴリズムは長期間パスワードを 保持しておくためにデザインされたアルゴリズムです。 Django では デフォルトで使われていません。サードパーティのライブラリを必要とする からです。しかし、 bcrypt をサポートするにはちょびっとの労力で 使えるように Django は配慮してくれています。
Bcrypt をデフォルトのアルゴリズムで使うには、以下に従ってください。
py-bcrypt ライブラリをインストールしてください(
sudo pip install py-bcrypt
を実行するか、ライブラリを
ダウンロードして、 python setup.py install
を使って
インストールしてください。)
PASSWORD_HASHERS
を設定してください。リスト内で
BCryptPasswordHasher
を先頭へ。セッティングファイルは
こうなります:
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher',
'django.contrib.auth.hashers.CryptPasswordHasher',
)
(リストの中の他の項目は、そのままにしておいてください、または Django がパスワードをアップグレードできないようにしてください。 下部を見てください)
今、Django は Bcrypt をデフォルトの パスワード保存アルゴリズムとして使おうとします。
bcrypt を使う他の方法
Django 内で bcrypt を用いる方法はいくつかあります。 Django の bcrypt サポート同士では直接的に互換性がありません。 アップグレードするために、フォームの bcrypt$(生の bcrypt アウトプット)内で、データベースのハッシュを修正する必要が あります。例えば: `bcrypt$$2a$12$NT0I31Sa7ihGEWpka9ASYrEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy
PDKDF2 と、 bcrypt アルゴリズムは、沢山のイテレーションとハッシュの循環を
用います。これはシステムへの攻撃の手を遅めます。ハッシュ化された
パスワードによって攻撃に立ち向かいます。しかし、コンピュータのマシンパワー
の向上とともに、必要なイテレーションの数も増加しました。それ相当なものを
選んでいます( Django のリリースの度に数を増やしてます)が、その強度を
増したい時もあれば減らしたい時もあるでしょう、セキュリティ環境に応じて、
または実行環境に応じて。そうするために、サブクラスを作り適切なアルゴリズム
と iterations
パラメータの上書きをするでしょう。たとえば、イテレーション
の回数を PBKDF2 で増加させるには:
サブクラスを django.contrib.auth.hashers.PBKDF2PasswordHasher
という
名前で作ります。:
from django.contrib.auth.hashers import PBKDF2PasswordHasher
class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
"""
PBKDF2PasswordHasher のサブクラスで百回以上イテレーションします
"""
iterations = PBKDF2PasswordHasher.iterations * 100
プロジェクトのどこかでこれを保存してください。例えば、 myproject/hashers.py
のようなファイルを置くのがよいでしょう。
2. PASSWORD_HASHERS
の中の最初の項目として新しいハッシュを加え
ます:
PASSWORD_HASHERS = (
'myproject.hashers.MyPBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher',
'django.contrib.auth.hashers.CryptPasswordHasher',
)
これだけで – Django は PBKDF2 を使ってパスワードを保存する時に、もっと 沢山のイテレーションを用いれるようになりました。
ログインする時に、パスワードがアルゴリズムよりも好ましいもので保存されて いれば、 Django は自動的にアルゴリズムをそちらにアップグレードします。 この意味は、古い Django でもユーザがログインするたびにセキュアなものに なるということです、そしてまた新しく(そしてより良い)パスワードの 保持アルゴリズムが作られるたびにそちらへ切り替えられるということです。
しかしながら、 Django がアップグレードできるパスワードはアルゴリズムとして
PASSWORD_HASHERS
のなかで宣言されているものだけです。新しい
システムにアップグレードする時には、 以前使っていたものを削除しない こと
を気をつけてください。もし削除してしまうと、消去してしまったアルゴリズムを
いつまでもアップグレードできないでいることになります。
models.
AnonymousUser
¶django.contrib.auth.models.AnonymousUser
は
django.contrib.auth.models.User
と同じインタフェースを実装した
クラスですが、以下の点で User
と異
なります:
id
は常に None
です。is_staff
および
is_superuser
は常に
False
です。is_active
は常に False
です。groups
および
user_permissions
は常に空で
す。is_anonymous()
は False
でなく True
を返します。is_authenticated()
は
True
でなく False
を返します。set_password()
,
check_password()
,
save()
,
delete()
,
set_groups()
および
set_permissions()
は
NotImplementedError
を送出します。おそらく、実践上意識して AnonymousUser
オブジェクトを使う必要はないはずです。とはいえ、匿名ユーザは次節で述べるよ
うな形で Web リクエストで使われています。
INSTALLED_APPS
に 'django.contrib.auth'
を追加した直後に
manage.py syncdb
を実行すると、スーパユーザの作成を促す
プロンプトを表示します。後でスーパユーザを作成したい場合には、以下のように
コマンドラインユーティリティを使います:
manage.py createsuperuser --username=joe --email=joe@example.com
ユーティリティはパスワードの入力を促します。入力すると、ユーザは即座に作成
されます。 --username
や --email
オプションを省
略すると、ユーティリティはそれらの値を入力するよう促します。
古い Django も使っている場合、以前からあるコマンドラインのスーパユーザ作成 方法も使えます:
python /path/to/django/contrib/auth/create_superuser.py
/path/to/
は自分のシステムの Django コードベースへのパスに応じて読
み変えて下さい。 manage.py
は自動的に正しいパスと環境変数を決定するので、
manage.py
を使うよう推奨します。
ユーザに追加の情報をひもづけて保存したい場合のために、 Django ではサイトご とにユーザに関連付けられた「ユーザプロファイル」を取り出すためのメソッドを 提供しています。
ユーザプロファイルを利用するには、まず、ユーザにひもづけて保存したい情報を
入れるためのフィールドや持たせたいメソッド、そして
User
モデルへの user
という名前で
OneToOneField
を持ったモデルを定義します。
OneToOneField
には
User
に対してユーザごとにモデルが一つだけ生成
されるようにします。例をあげると:
from django.contrib.auth.models import User
class UserProfile(models.Model):
# このフィールドが必要です.
user = models.OneToOneField(User)
# 他のフィールドはこちらにあります
accepted_eula = models.BooleanField()
facorite_animal = models.CharField(max_length=20, default="Dragons.")
このモデルをあるサイトのユーザプロファイルモデルにするには、
AUTH_PROFILE_MODULE
に以下の内容をドット区切りの文字列で指定しま
す:
manage.py startapp
で
アプリケーションを作成するときに指定する名前を全て小文字にしたもの)。例えば、プロファイルモデルが UserProfile
という名前のクラスで、
accounts
というアプリケーションで定義されているなら、設定値は以下のよう
になるでしょう:
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
ユーザプロファイルモデルが定義されていて、この規則通りになっていた場合、
User
のオブジェクトは、
get_profile()
というメソッドを
持つでしょう。 – これは User
ユーザ
プロファイルモデルに関連づけられたインスタンスを返します。
get_profile()
のメソッドは、
プロファイルを作る訳ではありません。もし存在しないものがあれば、
自身でユーザモデルの django.db.models.signals.post_save
のハンドル
のシグナルを登録する必要と、ハンドラーの中で、 created
が True
ならばユーザプロファイルと関連させて作るようにします:
# models.py の中で
from django.contrib.auth.models import User
from django.db.models.signals import post_save
# 上のユーザプロファイルの定義
# ...
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
See also
シグナル シグナルについての詳しい情報です。
ここまでのドキュメントは、認証関連のオブジェクトを操作するための低水準の
API について扱ってきました。より高水準の API では、 Django はこれらの認証フ
レームワークを リクエストオブジェクト
シ
ステム内にフックできます。
まず、 SessionMiddleware
およ
び AuthenticationMiddleware
を
MIDDLEWARE_CLASSES
設定に追加して、これらのミドルウェアをインス
トールします。詳しくは
セッションのドキュメント を参照してください。
ミドルウェアをインストールしたら、ビューから
request.user
にアクセスできるように
なります。 request.user
は現在ログイ
ンしているユーザの User
オブジェクトを
表します。ユーザがログインしていなければ、
request.user
は
AnonymousUser
のインスタンスになります
(前節を参照してください)。ログインユーザと匿名ユーザは、
is_authenticated()
で以下のように
区別できます:
if request.user.is_authenticated():
# Do something for authenticated users.
else:
# Do something for anonymous users.
Django では、 django.contrib.auth
の中で、
authenticate()
と
login()
という二つの関数を提供しています。
authenticate
()¶あるユーザ名とパスワードに対する認証を行うには、
authenticate()
を使ってください。この関数
は二つのキーワード引数、 username
と password
をとり、ユーザ名
に対してパスワードが有効であった場合に
User
オブジェクトを返します。パス
ワードが無効だった場合には、
authenticate()
は None
を返します。例
えば:
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
if user.is_active:
print "You provided a correct username and password!"
else:
print "Your account has been disabled!"
else:
print "Your username and password were incorrect."
login
()¶ユーザをログインさせるには、ビューの中で
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:
if user.is_active:
login(request, user)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.
authenticate()
は最初に呼び出してください
ユーザを手動でログインさせる場合、 login()
を呼び出す前に 必ず authenticate()
を呼び出してください。 authenticate()
は、
User
オブジェクトに、そのユーザが
認証バックエンドによって正しく認証されたことを示す属性を付加します。
(詳しくは 認証バックエンドのドキュメント を参照してください)
この情報が後でログインの処理で必要だからです。
django.contrib.auth.hashers
モジュールは関数セットを
ハッシュ化したパスワードの作成と有効化のために提供しています。
独立してそれらを使うことが出来ます。check_password
()¶リリースノートを参照してください
ユーザ認証を手動で行うために平文パスワードとデータベース上のハッシュ化
パスワードを比較したい場合には、
django.contrib.auth.hashers.check_password()
という便宜関数を使えます。この関数は、調べたい平文パスワードと、比較対
象のデータベースに格納されているユーザの password
フィールド全体の
二つの引数をとり、二つが一致すれば True
を、そうでなければ
False
を返します。
make_password
()¶リリースノートを参照してください
アプリケーションの中で使うフォーマット通りにハッシュ化したパスワードを作り
るには、二つの引数をとります: ハッシュ化するアルゴリズムとプレーンテキスト
のパスワードです。今サポートされているアルゴリズムは
: 'sha1'
, 'md5'
で、もし crypt
のライブラリがインストールされ
ていれば、それも使えます。もし、二つ目の引数が None
だと、使えない
パスワードがかえってきます(一つは、
django.contrib.auth.hashers.check_password()
によって受け付けられ
ません)
is_password_usable
()¶リリースノートを参照してください
与えられた文字列がハッシュ化されたパスワードであれば、それをチェックしま
す。 django.contrib.auth.hashers.check_password()
に反しないかが
確かめられます。
logout
()¶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()
の 後で
行ってください。
リリースノートを参照してください
auth 認証のフレームワークは二つ signals を使います。それは、ユーザがログインまたはログアウトした時のお知らせ のためです。
django.contrib.auth.signals.
user_logged_in
¶ユーザがログインに成功した時に送信します。
このシグナルが引数で送られます:
sender
request
HttpRequest
のインスタンスです。user
django.contrib.auth.signals.
user_logged_out
¶ユーザがログアウトする時に送信するものは
sender
None
を返します。request
HttpRequest
instance.user
None
を返します。ページへのアクセスを制限する単純で生真面目な方法は、
request.user.is_authenticated()
をチェックして、ログインページにリダイレクトするというものです:
from django.http import HttpResponseRedirect
def my_view(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/?next=%s' % request.path)
# ...
あるいは、エラーメッセージを出しても構いません:
def my_view(request):
if not request.user.is_authenticated():
return render_to_response('myapp/login_error.html')
# ...
decorators.
login_required
([redirect_field_name=REDIRECT_FIELD_NAME, 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
に値を設定した場合、ログインテンプレート
もそれに応じて変更する必要があります、テンプレートのコンテキスト(context)
変数が保持するリダイレクトパスは redirect_field_name
で設定した値を、
"next"
(通常)のかわりにキーとして扱うからです。
リリースノートを参照してください
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
に適切な Django のビュー関数
を対応づけておかねばなりません。例えば URLconf に以下のような行を設定します:
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
views.
login
(request[, template_name, redirect_field_name, authentication_form])¶URL name: login
the URL documentation に URL パターンについて 詳細にのっているので見てください。
django.contrib.auth.views.login
は以下のような処理を行います:
GET
で呼び出されると、同じ URL に対して POST を行うためのログ
インフォームを表示します。これについては後でもう少し説明します。POST
で呼び出されると、ユーザのログイン処理を試みます。ログイ
ンに成功すると、ビューは next
に示された URL にリダイレクトし
ます。 next
を指定しない場合、
settings.LOGIN_REDIRECT_URL
(デフォルト値は /accounts/profile/
) にリダイレクトします。ロ
グインに失敗すると、ログインフォームを再度表示します。開発者は registration/login.html
という名前のテンプレート上でログイ
ンフォームを提供せねばなりません。 Django はこのテンプレートに、以下の
3 つのテンプレートコンテキスト変数を渡します:
form
: ログインフォームを表現する Form
オブジェクトです。 Form
オブジェクトの詳細
は forms のドキュメント を参照してく
ださい。next
: ログイン成功後にリダイレクトされる先の URL です。 URL
にはクエリ文字列を含めてかまいません。site
: 現在の Site
,
SITE_ID
のセッティングに従っています。もし、サイト
フレームワークがインストールされていなければ、これは、
RequestSite
のインスタンスが
セットされます。これはサイトの名前とドメインを現在の
HttpRequest
から取ってきます。site_name
: site.name
のための別名(alias)です。もし、
サイトフレームワークがインストールされていなければ、
request.META['SERVER_NAME']
の値がセットされます。サイトについてもっと知りたければ
“sites” フレームワーク を見てください。registration/login.html
テンプレートを呼び出したくないのなら、
URLconf を通じて外部パラメタ template_name
をビューに渡してください。
例えば、 myapp/login.html
を使いたければ、URLconf の行は以下の
ようになります:
(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
GET
フィールドの名前を指定できます。 GET
フィールドは、
redirect_field_name
からビューへの、
ログイン後のリダイレクト先を含むURLを設定してください。
通常では、このフィールドは next
です。
編集の雛型にできるような registration/login.html
テンプレートの
例を以下に示します。このテンプレートは、 content
ブロックの定義された
base.html
があるという前提で書かれています:
{% extends "base.html" %}
{% load url from future %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url 'django.contrib.auth.views.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>
{% endblock %}
リリースノートを参照してください
もし、他の認証を使っているならば( 他の認証データソースを使う を見て
ください)カスタムされた認証フォームを通って、 authentication_form
パラメータを経てログインビューへと行きます。このフォームは request
キーワード引数を自身の __init__
メソッドの中で受け取らなくては
いけません。そして、 get_user
メソッドは認証されたユーザーオブジェクト
を返します。(このメソッドは、成功したフォームバリデーションの
後に一度だけ呼ばれます。)
リリースノートを参照してください
login()
のビューと その他の組み込みビュー は今、
全て TemplateResponse
のインスタンス
を返します。これは、レスポンスデータをレンダリング前に容易に改変できる
ようにします。もっと情報が欲しければ
TemplateResponse documentation を見て
ください。
login()
ビューに加えて、認証システムはその他の役に立つビューを
django.contrib.auth.views
: に持っています。:
logout
(request[, next_page, template_name, redirect_field_name])¶ユーザをログアウトさせます。
URL name: logout
URL のドキュメント を見てください。もっと 詳しく URL パターンを使う上での情報が載っています。
オプション引数:
next_page
: ログアウト後にリダイレクトされる URL です。template_name
: ログアウトページのテンプレートの完全な名前です。
この引数を省略すると、デフォルト値の
registration/logged_out.html
を使います。redirect_field_name
: GET
フィールドの名前で、ログアウト後の
リダイレクト先 URL を含みます。 GET
パラメータが渡されると
next_page
が上書きされます。テンプレートコンテキスト:
title
: “Logged out” の文字列を翻訳した値になります。site
: 現在の Site
で、
SITE_ID
のセッティングに従っています。もし、サイト
フレームワークをインストールしていなければ、これは
RequestSite
のインスタンス
がセットされ、サイトの名前てドメインを現在の
HttpRequest
から取ってきます。site_name
: site.name
のための別名(alias)です。もし、
サイトフレームワークがインストールされていなければ、
request.META['SERVER_NAME']
の値がセットされます。サイトについてもっと知りたければ
“sites” フレームワーク を見てください。logout_then_login
(request[, login_url])¶ユーザをログアウトさせてから、ログインページにリダイレクトします。
オプション引数:
login_url
: ログインページへのリダイレクト先です。この引数を省
略すると、デフォルト値の settings.LOGIN_URL
を使います。password_change
(request[, template_name, post_change_redirect])¶ユーザがパスワードを変更できるようにします。
オプション引数:
template_name
: パスワード変更ページのテンプレートの完全な名前
です。この引数を省略すると、デフォルト値の
registration/password_change_form.html
を使います。
post_change_redirect
: パスワードの変更に成功した場合の
URLリダイレクト先です。
リリースノートを参照してください
password_change_form
: “パスワードの変更” フォームのカスタマイズ
は、 user
のキーワード引数を受け取らなくてはいけません。
フォームは実際にウーザのパスワードが変更される責任があります。
通常では、 PasswordChangeForm
になります。
テンプレートコンテキスト:
form
: パスワード変更のためのフォームです。password_change_done
(request[, template_name])¶ユーザがパスワードを変更した後のページを表示するためのビューです。
URL name: password_change_done
オプション引数:
template_name
: パスワード変更完了ページのテンプレートの完全な
名前です。この引数を省略すると、デフォルト値の
registration/password_change_done.html
を使います。password_reset
(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email])¶ユーザがパスワードをリセットできるように、一回しか使用できないリンクを 作成します。また、新たなパスワードをメールで送信します。
from_email
引数が加えられました。set_unusable_password()
を見てください)は、パスワードのリセットをリクエストできません。
外部の認証ソース、例えばLDAPのようなものを使う際の悪用を防ぐためです。URL name: password_reset
オプション引数:
template_name
: パスワードリセットページのテンプレートの完全な
名前です。この引数を省略すると、デフォルト値の
registration/password_reset_form.html
を使います。
email_template_name
: 新しいパスワードを e-mail で送信する際に
使うテンプレートの完全な名前です。この引数を省略すると、デフォル
ト値の registration/password_reset_email.html
を使います。
subject_template_name
: 新しいパスワードのemailを生成するのに使う
テンプレートのフルネームです。デフォルトでは
registration/password_reset_email.html
が設定されています。
リリースノートを参照してください
password_reset_form
: パスワードのセットに使うフォームです。
デフォルトでは
PasswordResetForm
が設定されています。
token_generator
: パスワードのチェックに使うクラスのインスタンスで
す。通常は default_token_generator
に設定されています、これは
django.contrib.auth.tokens.PasswordResetTokenGenerator
のインスタ
ンスです。
post_reset_redirect
: パスワードの変更が成功した後にリダイレクト
する URL です。
from_email
: 有効な email アドレスです。通常 Django が使うのは
DEFAULT_FROM_EMAIL
です。
テンプレートコンテキスト:
form
: パスワードリセットのためのフォームです。
(上にある password_reset_form` を見てください)Email テンプレートコンテキスト:
email
: user.email
の別名です。user
: 現在の User
で、
email
フォームフィールドに従っています。アクティブユーザのみ
が、パスワードをリセットすることができます。(
User.is_active is True
)site_name
: sit.name
のエイリアス(別名)です。もし、
インストール済みのサイトフレームワークがない場合は、
request.META['SERVER_NAME']
の値をセットします。これについては “sites” フレームワーク を
ご覧ください。domain
: site.domain
のエイリアス(別名)です。もし、
サイトフレームワークがインストールされていない場合、これは
request.get_host()
の値をセットします。protocol
: http or httpsuid
: ユーザのIDは36進数でエンコードされます。token
: トークンはパスワードが有効なものかをチェックします。registration/password_reset_email.html
( email ボディテンプレー
ト)にサンプルがあります:
{% load url from future %}
誰かがパスワードの変更を求めたら {{ email }} のように
email から送られたリンクへと飛ぶことになります。下のリンクに従ってください。:
{{ protocol }}://{{ site_name }}{% url 'auth_password_reset_confirm' uidb36=uid token=token %}
同じテンプレートコンテキストが、サブジェクトテンプレートに使われる 時、サブジェクトは一行のプレーンテキストでなくてはなりません。
views.
password_reset_done
(request[, template_name])¶ユーザがパスワードをリセットした後のページを表示するためのビューです。
このビューは password_reset()
ビューが post_reset_redirect
の URL セットを所持していない時にデフォルトで呼ばれます。
オプション引数:
template_name
: パスワードリセット完了ページのテンプレートの完
全な名前です。この引数を省略すると、デフォルト値の
registration/password_reset_done.html
を使います。password_reset_confirm
(request[, uidb36, token, template_name, token_generator, set_password_form, post_reset_redirect])¶Presents a form for entering a new password.
オプション 引数:
uidb36
: 36進数でエンコードされたユーザのIDです。デフォルトでは
None
です。token
: パスワードが有効かをチェックするためのトークンです。
デフォルトでは None
です。template_name
: 確定したパスワードのビューを表示するテンプレート
のフルネームです。token_generator
: パスワードをチェックするためのクラスのインスタ
ンスです。これは default_token_generator
がデフォルトです。
そして、 django.contrib.auth.tokens.PasswordResetTokenGenerator
のインスタンスでもあります。set_password_form
: パスワードをセットするためのフォームとして
使用されます。 SetPasswordForm
がデフォルトです。post_reset_redirect
: パスワードのリセットが終了した後に
リダイレクトされる先です。デフォルトでは None
です。テンプレートコンテキスト:
form
: 新しいユーザのパスワードをセットするための
フォームです(上にある set_password_form
を見てください)validlink
: Boolean 型です。 True でリンクが有効か(
uidb36 とトークンの組み合わせ)またはまだ使われていないかです。password_reset_complete
(request[, template_name])¶ユーザにパスワードの変更が成功したということを伝えるためのビューです。
URL name: password_reset_complete
オプション引数:
template_name
: ビューを表示するためのテンプレートのフルネームで
す。registration/password_reset_complete.html
がデフォルトの
値になります。redirect_to_login
(next[, login_url, redirect_field_name])¶ログインページへリダイレクトします、ログインに成功したら、トップ画面で はなく、違う URL へと戻ります。
必要な 引数:
next
: ログインに成功した後のリダイレクト先の URL です。オプション 引数:
login_url
: リダイレクトするログインページの URL です。
デフォルトでは settings.LOGIN_URL
となります。redirect_field_name
: GET
フィールドに含まれているログアウト後
にリダイレクトする先の URL です。 GET
パラメータが渡されていれば
next
を上書きします。組み込みビューを使いたくないけれども、フォームクラスを書かずに済ませたい場
合のために、認証システムは組み込みのフォームを
django.contrib.auth.forms
でいくつか提供しています:
AdminPasswordChangeForm
¶Admin インタフェースでユーザのパスワード変更に使われているフォームです。
AuthenticationForm
¶ユーザをログインさせるためのフォームです。
PasswordChangeForm
¶ユーザにパスワードを変更させるためのフォームです。
PasswordResetForm
¶パスワードをリセットし、新たなパスワードを送信するためのフォームです。
SetPasswordForm
¶古いパスワードを入力することなく、パスワードを変更させるための フォームです。
UserChangeForm
¶ユーザ情報とパーミッションを変更するためのアドミンインターフェースです
UserCreationForm
¶新たなユーザを作成するためのフォームです。
特定のパーミッションやその他のテストの結果に応じたアクセスの制限には、前節 で説明したの本質的に同じことをします。
一番簡単な方法は、ビュー内で直接
request.user
に対するテストを実行す
るというものです。例えば、以下のビューではユーザがログイン済みで、かつ
polls.can_vote
というパーミッションを持っているかチェックします:
def my_view(request):
if not request.user.has_perm('polls.can_vote'):
return HttpResponse("You can't vote in this poll.")
# ...
user_passes_test
(func[, login_url=None])¶user_passes_test
デコレータを使えば、手間を省けます:
from django.contrib.auth.decorators import user_passes_test
@user_passes_test(lamda u: u.has_perm('polls.can_vote'))
def my_view(request):
...
ここでは、簡単な例としてパーミッションのテストに
user_passes_test()
を使っています
が、単にあるユーザがあるパーミッションを有しているかをテストしたいだけ
なら、後で解説する
django.contrib.auth.decorators.permission_required()
デコレータ
を使えます。
user_passes_test()
には必須の引数
が一つあります。この引数は、 User
を引数に取り、ユーザにページのビューを許可する場合には True
を返す
呼び出し可能オブジェクトでなければなりません。
user_passes_test()
は
User
が匿名かどうかを自動的に調べ
ないので注意してください。
user_passes_test()
はオプション
の引数として login_url
をとります。この引数を使うとログインページへ
の URL を指定できます (デフォルトでは
settings.LOGIN_URL
になります)。
例えば:
from django.contrib.auth.decorators import user_passes_test
@user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')
def my_view(request):
...
permission_required
デコレータ¶decorators.
permission_required
([login_url=None, raise_exception=False)¶あるユーザが特定のパーミッションを有しているかのチェックは、比較的よく
ある操作なので、 Django はショートカットとして
permission_required()
という
デコレータを用意しています。このデコレータを使うと、上の例は以下のよう
に書き直せます:
from django.contrib.auth.decorators import permission_required
@permission_required('polls.can_vote')
def my_view(request):
...
As for the User.has_perm()
method, permission names take the form
"<app label>.<permission codename>"
(すなわち polls.choice
は
は polls
アプリケーションのモデルへのパーミッションです.)
permission_required()
もまた、
login_url
を引数に取れます。例えば:
from django.contrib.auth.decorators import permission_required
@permission_required('polls.can_vote', login_url='/loginpage/')
def my_view(request):
...
login_required
デコレータと同様、 login_url
のデフォルト値は
settings.LOGIN_URL
です。
リリースノートを参照してください
raise_exception
パラメータが追加されました。もし、パラメータが
与えられると、でコレータは PermissionDenied
を送出します。 the 403 (HTTP Forbidden) view
を、ログインページへのリダイレクトの代わりに出します。
アクセスを 汎用ビュー に制限するには、
View.dispatch
という
クラスのメソッドをデコレートする必要があります。
クラスのデコレート の詳細を確認してください。
class-based generic view にアクセスを制限 するにはビューを囲む薄いラッパコードを書き、URLconf を変更して、 ジェネリックビュー自体ではなくラッパコードを指すようにします。例えば:
from django.views.generic.date_based import object_detail
@login_required
def limited_object_detail(*args, **kwargs):
return object_detail(*args, **kwargs)
Django には単純なパーミッション機構がついてきます。このパーミッション機構は 特定のユーザやユーザのグループに対してパーミッションを結びつける手段を提供 します。
パーミッション機構は Django の admin サイトでも使われていますが、自作のコー ド内でも自由に使えます。
パーミッションはオブジェクトインスタンスごとではなく、オブジェクトの型ごと にグローバルに設定されます。例えば、「Mary はニュース記事を変更できる」のよ うには書けますが、現状では、「Mary はニュース記事を変更できる。ただし彼女が 書いた分だけ」とか、「Mary はある状態にある記事か、ある日時に出版されたか、 ある ID の記事だけを変更できる」のようには書けません。後者の機能については は、現在 Django の開発者達が議論中です。
INSTALLED_APPS
設定に django.contrib.auth
を追加している場合、
インストールされている全てのアプリケーションのモデルについて、追加 (add)、
変更 (change)、および削除 (delete) というデフォルトのパーミッションが作成さ
れます。
これらのパーミッションは、 manage.py syncdb
を実行した
ときに生成されます。厳密には、 django.contrib.auth
を
INSTALLED_APPS
設定に追加した直後に syncdb
を実行する
と、その時インストールされていた全てのアプリケーションと、新たに追加したア
プリケーションのデフォルトパーミッションが作成されます。以後、
manage.py syncdb
を実行するたびに、新たに追加されたモデ
ルのデフォルトパーミッションが生成されます。
もし、アプリケーションを app_label
foo
という名前にしていてモデルの名前を Bar
だと仮定します、
標準のパーミッションをテストするにはこのようにします:
user.has_perm('foo.add_bar')
user.has_perm('foo.change_bar')
user.has_perm('foo.delete_bar')
カスタムのパーミッションを生成するには、 permissions
という
モデルのメタ属性 を使います。
この例では、 Task モデルに三つのカスタムパーミッションを作っています、 すなわち Task インスタンスによってユーザが出来るアクションが決まります。 アプリケーション内でのコードは:
class Task(models.Model):
...
class Meta:
permissions = (
("view_task", "Can see available tasks"),
("change_task_status", "Can change the status of tasks"),
("close_task", "Can remove a task by setting its status as closed"),
)
この定義の役割は特別なパーミッションを追加することだけです。
manage.py syncdb
を実行すると、コードは
パーミッションをチェックする役割を負います。それが実行されるのは、
ユーザがアプリケーションによって機能へとアクセスしようとする時
(タスクを見て、タスクのステータスを変え、タスクを閉じるような動作)
です。上の例に続ければ、ユーザがタスクを見る時にそれと共にチェックし
ます:
user.has_perm('app.view_task')
models.
Permission
¶Permission
オブジェクトには以下のフィー
ルドがあります:
Permission.
name
¶必須です。50 文字以下です。例: 'Can vote'
Permission.
content_type
¶必須です。インストール済みの Django モデルのレコードが入った
django_content_type
データベーステーブルへの参照です。
Permission.
codename
¶必須です。 100 文字以下です。例: 'can_vote'
Permission
オブジェクトは、他の
Django モデル と同じく、標準的なデータアクセスメソッ
ドを備えています。
Meta
クラス内でカスタムパーミッションが定義される一方、
直接的にパーミッションを作ることもまたできます。例えば、
myapp
の BlogPost
モデルに対して、 can_publish
パーミッションを作ろうとすると:
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get(app_label='myapp', model='BlogPost')
permission = Permission.objects.create(codename='can_publish',
name='Can Publish Posts',
content_type=content_type)
パーミッションは自身のクラスの user_permissions
アトリビュートか、
Group
の permissions
アトリビュートから
User
へと割り当てることができます。
RequestContext
を使っている場合、ログイン
ユーザとそのパーミッションに
テンプレートコンテキスト (template context) を使っ
てアクセスできます。
技術的な話題
デフォルトの設定では、テンプレートコンテキストに
RequestContext
を使うようになっていて、
かつ TEMPLATE_CONTEXT_PROCESSORS
の設定に
"django.contrib.auth.context_processors.auth"
が入っています。この場合にのみ、
上記の変数をテンプレートコンテキストの中で使えるようになります。詳しくは
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 }}
に入っ
ています。この変数はパーミッションオブジェクトをテンプレートで扱いやすくす
るためのプロキシ (proxy) である、
django.contrib.auth.context_processors.PermWrapper
のインスタンスです。
django.contrib.auth.context_processors
の中に PermWrapper
が置かれました。{{ perms }}
オブジェクトに対して 1 段の属性参照を行うと、実際には
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 %}
グループは、パーミッションを適用するユーザのカテゴリを作ったり、一連のユー ザに何らかのラベルを適用するための汎用的な手段です。一人のユーザは複数のグ ループに所属できます。
グループに所属したユーザは、そのグループに許可されているパーミッションを自
動的に得ます。例えば、 Site editors
というグループに
can_edit_home_page
というパーミッションをがあれば、そのグループに属する
ユーザはみな, can_edit_home_page
のパーミッションを持ちます。
パーミッションだけではなく、グループはユーザをカテゴリに分けてラベルを付け
たり、機能を拡張したりできます。例えば、 '特別なユーザ'
のグループを作
成して、そのグループのユーザ向けに、例えばサイト内のメンバー限定エリアへの
アクセスを提供したり、メンバーだけに email メッセージを送るといった、特別
な処理を行うコードを書けます。
models.
Group
¶Group
オブジェクトはそれに続くフィールドを
持っています:
Group.
name
¶必須です。 80文字以下です。どんな文字でも使えます。例えば:
'Awesome Users'
このように。
Group.
permissions
¶Many-to-many フィールド Permissions
:
group.permissions = [permission_list]
group.permissions.add(permission, permission, ...)
group.permissions.remove(permission, permission, ...)
group.permissions.clear()
ほとんどのケースでは、 Django についてくる認証メカニズムで十分のはずですが、 場合によっては別の認証データソース (authentication source) をフックしたい、 すなわち、Django 外のユーザ名やパスワードデータや認証メソッドを使いたいよう なケースもあることでしょう。
例えば、会社が LDAP 構成を使って社員のユーザ名やパスワードを管理していると しましょう。ネットワーク管理者にとっても、またユーザ自身にとっても、 LDAP とDjango ベースのアプリケーションの双方で別々のアカウントを維持するのはいさ さか骨の折れる作業です。
こうした状況を扱うために、 Django の認証システムは別の認証ソースをプラグイ ンできるようになっています。 Django がデフォルトで使っているデータベースの スキームをオーバライドしたり、デフォルトのシステムを他のシステムと並列して 動作させたりできます。
authentication backend reference を見てください。 もっと詳しい情報が載っています。
舞台裏では、 Django は認証に使う「認証バックエンド」のリストを維持していま
す。前述の 「ユーザをログインさせる」 で説明したように
django.contrib.auth.authenticate()
を呼び出すと、Django は全ての認
証バックエンドにわたって認証テストを試みます。最初の認証メソッドに失敗する
と次の認証バックエンド、という具合にして、認証に成功しない限り、全てのバッ
クエンドを試すまで続けます。
認証に使うバックエンドのリストは AUTHENTICATION_BACKENDS
設定に
指定します。この値は Python モジュールパス名からなるタプルで、認証方法を実
装したクラスの名前を指定します。認証クラスは Python パス上のどこにあっても
かまいません。
デフォルトでは、 AUTHENTICATION_BACKENDS
の値は:
('django.contrib.auth.backends.ModelBackend',)
に設定されています。このクラスは、 Django のユーザデータベースをチェックす る認証スキームです。
AUTHENTICATION_BACKENDS
の順番には意味があり、同じユーザ名とパス
ワードが複数のバックエンドで有効な値であったとしても、 Django は最初にユー
ザ名とパスワードがマッチした時点で認証処理を停止します。
Note
一度ユーザが認証されると、 Django はユーザのセッション内でどのバック
エンドによってユーザが認証されたかを保持します。そして、同じバックエンド
を「認証されたユーザ」であることが必要とされる時にアクセスします。
この効率性が意味するのは、認証ソースが一回のセッションを基礎として
キャッシュされるということです。だから、もし
AUTHENTICATION_BACKENDS
を変更すると、セッションデータをクリア
しなければ、異なる方法で再認証することができません。これのシンプルな方法
は、 Session.objects.all().delete()
を実行することです。
認証バックエンドの実体は、 get_user(user_id)
と
authenticate(**credentials)
という二つのメソッドを実装したクラスです。
get_user
メソッドはユーザ名、データベース ID などを表す引数
user_id
をとり、対応する User
オブジェクトを返します。
authenticate
メソッドは証明情報、すなわちユーザ名とパスワードなどをキー
ワード引数の形で受け取ります。ほとんどの場合、以下のような形式をとります:
class MyBackend(object):
def authenticate(self, username=None, password=None):
# Check the username/password and return a User.
以下のようにトークンに対する認証を行うようにも書けます:
class MyBackend(object):
def authenticate(self, token=None):
# Check the token and return a User.
どちらの方法でも、 authenticate
は受け取った証明情報をチェックし、証明
情報が有効な場合、対応する User
オブジェクトを返さねばなりません。証明
情報が無効なら、 None
を返します。
Django の admin システムは、冒頭で説明した Django の User
オブジェクト
と強くカップリングしています。従って、今のところ自作の認証バックエンドを扱
うには、 (LDAP ディレクトリや外部の SQL データベースなどのような) 別のバッ
クエンド上のユーザに対して Django の User
オブジェクトを生成するのがベ
ストです。あらかじめスクリプトを書いておいてもよいですし、ユーザが最初にロ
グインした際に、 authenticate
メソッドでその処理を行うようにしてもよい
でしょう。
以下に示すバックエンドの例では、 settings.py
ファイルに定義されたユーザ
名とパスワードに対して認証を行い、ユーザが最初に認証を行ったときに User
オブジェクトを生成します:
from django.conf import settings
from django.contrib.auth.models import User, check_password
class SettingsBackend(object):
"""
セッティングにそぐわない認証の ADMIN_LOGIN and ADMIN_PASSWORD
ログインネームとパスワードのハッシュを使ってみます。例えば:
ADMIN_LOGIN = 'admin'
ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
"""
supports_inactive_user = False
def authenticate(self, username=None, password=None):
login_valid = (settings.ADMIN_LOGIN == username)
pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
if login_valid and pwd_valid:
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
# Create a new user. Note that we can set password
# to anything, because it won't be checked; the password
# from settings.py will.
user = User(username=username, password='get from settings.py')
user.is_staff = True
user.is_superuser = True
user.save()
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
カスタムの認証バックエンドから、独自のパーミッションを提供できます。
認証バックエンドがパーミッション照会のための関数
(get_group_permissions()
,
get_all_permissions()
,
has_perm()
, および
has_module_perms()
) をサポートして
いる場合、ユーザモデルはパーミッションの照会をバックエンドに移譲します。
あるユーザに付与されるパーミッションの集合は、全てのバックエンドの返しうる パーミッションのスーパーセットです。すなわち、 Django はいずれかのバックエ ンドのパーミッションを、どのユーザにも付与できます。
前述の単純なバックエンドで、万能の管理ユーザを作る方法は、以下のようにとても 簡単です:
class SettingsBackend(object):
# ...
def has_perm(self, user_obj, perm, obj=None):
if user_obj.username == settings.ADMIN_LOGIN:
return True
else:
return False
この書き方だと、上の例でアクセスを認可されたユーザにはあらゆるパーミッショ
ンが許されます。バックエンドの認証関数はユーザオブジェクトを引数にとります。
また、ユーザオブジェクトの代わりに、
User
のコンストラクタと同じ引数も指定
できます。
認可の API は、 django/contrib/auth/backends.py で実装されています。この
バックエンドはデフォルトのバックエンドであり、ほとんどの場合
auth_permission
にパーミッションを問い合わせます。
リリースノートを参照してください
匿名ユーザは認証されていません。すなわち、有効な認証の情報が提供されていませ ん。しかしながら、権限が与えられてないから何もしなくてよいという意味ではありま せん。最も基本的な部分で、ほとんどの Web サイトはサイトの大部分を匿名ユーザ に対して見せています。そして、許可された匿名ユーザはコメントなどを投稿する ことができます。
Django のパーミッションフレームワークは、匿名ユーザに対してのパーミッションを 保持する場所を設けてはいません。ですが、匿名ユーザに対しての権限を指定するため の認証バックエンドのカスタムは基礎部分で許可されています。これは特に、 再利用できるアプリの作者に取って役に立つものです。認証バックエンドに権限につい ての全ての問題を任せてしまうことが出来ます。セッティングを必要とするというより 、例が匿名ユーザのコントロールです。
リリースノートを参照してください
アクティブでないユーザは、認証されていても is_active
が False
に
セットされているユーザです。しかし、これは何も認証されていないという意味で
はありません。例えば、そのようなユーザは自身のアカウントをアクティブにする
ことができます。
パーミッションシステム内での匿名ユーザに対してのサポートは、アクティブでな いユーザがしない、「何かをする権限を得ること」を許可しています。
これをバックエンドで有効にするには、クラスの supports_inactive_user
アトリビュートを True
にしなければいけません。
supports_inactive_user
属性が存在しないことは、
PendingDeprecationWarning
を送出します。もし、 Django 1.3 または、
1.4 ではこの警告は、 DeprecationWarning
にアップデートされています。
これは大きくうるさげに表示されます。加えて、 supports_inactive_user
が False
になっていると、 Django 1.5 ではアクティブでないユーザが
認証手続きでパスされることをサポートするでしょう。
Django のパーミッションフレームワークは、オブジェクトへのパーミッションを
基礎に持っています、でも、コアにその実装を持っていません。その意味は、
オブジェクトへのパーミッションは常に False
が返るか、または空っぽの
リスト(チェックがどう働いたかに依存します)が返ります。
Oct 26, 2017