web-dev-qa-db-ja.com

初期データフィクスチャのユーザー

fixtures/initial_data.jsonにデフォルトでいくつかのユーザーを作成して、テスト用の「サブジェクト」を用意しています。私が経験している問題はパスワードの生成です。 「フィールド」でパスワードを設定できましたが、ハッシュ化されたパスワードは生成されません。

[
    { "model": "auth.user",
        "pk": 1,
        "fields": {
            "username": "user1",
            "password": "password"
        }
    }
]

ユーザーのパスワードを生成する方法が必要です。これを手動で行い、{hash_method}${salt}${hashed_password}のような文字列を生成する必要がありますか?Djangoはそうですか?

51
Naftuli Kay

この場合(および少数のユーザーのみが必要な場合)に簡単なのは、管理者(パスワードを含む)を通じて偽のユーザーアカウントを作成し、を使用してフィクスチャーファイルにユーザーをダンプすることです。 dumpdata

$ python manage.py dumpdata auth.User --indent 4 > users.json

フィクスチャが自動的に作成され、後でloaddataで使用できます

(多くのテストユーザーが必要な場合は、1つの偽のアカウントを作成し、残りのフィクスチャでハッシュを使用できます)

https://docs.djangoproject.com/en/dev/ref/Django-admin/#dumpdata-appname-appname-appname-model

92
Timmy O'Mahony

OK、答えに同意しますが、元の質問に答えさせてください。

パスワードを「Djangoでハッシュ化されたはずです)」と取得する方法は?

ファイルを見てみましょうDjango/contrib/auth/hashers.py

def make_password(password, salt=None, hasher='default'):
    """
    Turn a plain-text password into a hash for database storage

    Same as encode() but generates a new random salt.  If
    password is None or blank then UNUSABLE_PASSWORD will be
    returned which disallows logins.
    """
    # ...

このセッション例をご覧ください。

./manage.py Shell

>>> from Django.contrib.auth.hashers import make_password, HASHERS
>>> make_password('test')
'pbkdf2_sha256$10000$vkRy7QauoLLj$ry+3xm3YX+YrSXbri8s3EcXDIrx5ceM+xQjtpLdw2oE='

# fix salt:
>>> make_password('test', 'abc')
'pbkdf2_sha256$10000$abc$MqJS5OAgSmf9SD9mfoY8fgLo8sSKmEcef0AjjMp1Q7w='

# use different (maybe faster, maybe unsafe!) hasher

In [12]: HASHERS
Out[12]:
{'bcrypt': <Django.contrib.auth.hashers.BCryptPasswordHasher object at 0x29c6d50>,
 'crypt': <Django.contrib.auth.hashers.CryptPasswordHasher object at 0x29c6f50>,
 'md5': <Django.contrib.auth.hashers.MD5PasswordHasher object at 0x29c6e10>,
 'pbkdf2_sha1': <Django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher object at 0x29c6bd0>,
 'pbkdf2_sha256': <Django.contrib.auth.hashers.PBKDF2PasswordHasher object at 0x29c6cd0>,
 'sha1': <Django.contrib.auth.hashers.SHA1PasswordHasher object at 0x29c6dd0>,
 'unsalted_md5': <Django.contrib.auth.hashers.UnsaltedMD5PasswordHasher object at 0x29c6ed0>,
 'unsalted_sha1': <Django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher object at 0x29c6e50>}

In [14]: [make_password('test', hasher=name) for name in HASHERS]
Out[14]:
['sha1$LdKsAbJRjlVP$2eb2346387cc510f576f2f11eebdfe18b20d1be1',
 'pbkdf2_sha256$10000$Ck8gtWQJnJ9x$M/OqP548d5KcPqFuVRgXb84unjYbYDH6oyimbDndE3k=',
 'pbkdf2_sha1$10000$BJqRu5OwylVF$hUvMLIzBujt9kPbML/dei1vLiMQ=',
 'crypt$$d9grSeqDhMFek',
 '098f6bcd4621d373cade4e832627b4f6',
 'sha1$$a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',
 'bcrypt$$2a$12$WlJP5zm2lmdJ4g/pSE1xF.d/8w.XRT5mo/vGlkKdglBtzcxKw7XJS',
 'md5$txHYmSYJKhD4$69286d4a1abd348fbddc9df7687e2ed4']

ハッシュのencodeメソッドを手動で使用することもできますが、上記のユーティリティ関数を使用すると簡単にカバーできます。

18
Tomasz Gandor

テスト用のフィクスチャを書いているときに、同じ問題に遭遇しました。ユニットテストでこれを処理する方法を次に示します。

Adminからデータを作成してフィクスチャにダンプすることはできますが、手動で行うことに依存することはあまり好きではありません。だからここに私がやることがある-

行ったとおりにフィクスチャを作成し、setUpメソッドでユーザー用のset_passwordsを作成します。

ser_fixture.json

[
    { "model": "auth.user",
        "pk": 1,
        "fields": {
            "username": "user1",
            "password": "password"
        }
    }
]

test_user.py

def setUp(self):
    self.User = get_user_model()

    # Fix the passwords of fixtures
    for user in self.User.objects.all():
        user.set_password(user.password)
        user.save()

このようにして、フィクスチャにパスワードをきれいに書き込み、必要なときにそれらを参照して、フィクスチャファイルを編集するだけでさらにフィクスチャを作成できます。

12
Gaurav Butola

@GauravButolaの答えに加えて、フィクスチャをロードし、パスワードを1ステップで修正するカスタム管理コマンドを作成しました。これは、テストフレームワークを使用してパスワードのセットアップを行わない場合に役立ちます。この例は、Django 1.11およびおそらく以前のバージョンで動作しています。

フィクスチャを提供するアプリに管理コマンドを追加します(これはpython3回なので、init pysを省略しました)。

yourapp/
    models.py
    fixtures/
        initial_data.json
    management/
        commands/
            initdata.py

Initdata.pyは次のようになります。

from Django.core.management import BaseCommand, call_command
from Django.contrib.auth.models import User
# from yourapp.models import User # if you have a custom user


class Command(BaseCommand):
    help = "DEV COMMAND: Fill databasse with a set of data for testing purposes"

    def handle(self, *args, **options):
        call_command('loaddata','initial_data')
        # Fix the passwords of fixtures
        for user in User.objects.all():
            user.set_password(user.password)
            user.save()

これで、initial_dataをロードし、有効なパスワードを取得できます:

./manage.py initdata
4
itsafire

データベースからユーザー情報をダンプします。

$ python manage.py dumpdata auth.User --indent 4 > users.json

データ固有のJSONフィクスチャのインポート/ロード:

$ python manage.py loaddata users.json
2
Cubiczx

本当にそうするでしょう。そんなに難しくないはずです。最も簡単な方法は、関数user.set_password私はそれが正しいと思い、彼らがそれをどのように行うか見てください。 python端末から関数を呼び出して、それを初期データにコピーすることができます!

0
mpen