#18157 closed New feature (fixed)
Document that setting PASSWORD_HASHERS for tests can make them much faster
Reported by: | Carl Meyer | Owned by: | nobody |
---|---|---|---|
Component: | Documentation | Version: | 1.4 |
Severity: | Normal | Keywords: | |
Cc: | kmike84@…, dan.fairs@…, dev@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
As discussed in this thread, the new default PBKDF2 password hasher in Django 1.4 is significantly slower by design than the previous MD5 hasher (so that cracking of passwords in an exposed password database is more time-consuming). It seems that for some test suites that authenticate a lot of users, this can slow down the overall test suite run-time by as much as a factor of two.
The workaround is simple: you can override the PASSWORD_HASHERS
setting to something like PASSWORD_HASHERS = ['django.contrib.auth.hashers.MD5PasswordHasher']
, just for tests. Given the speed difference, this workaround is probably worth documenting in the testing docs (with the caveat that of course your test suite then won't reveal any bugs in your real PASSWORD_HASHERS
setting).
Change History (12)
comment:1 by , 13 years ago
Cc: | added |
---|
comment:2 by , 13 years ago
Considering this workaround won't really test any password hashes, I wonder if having a dummy hasher would further improve test speeds.
Cheers,
AT
comment:3 by , 13 years ago
Triage Stage: | Unreviewed → Accepted |
---|
I believe md5 is really "fast enough" unless you are doing nothing else than hashing alone (haven't benchmarked). There is certain point of not having a dummy-hasher at all in Django.
comment:4 by , 13 years ago
As akaariai noted in the mailing list thread, it may also make sense to make this change in the test_sqlite settings file for running Django's own test suite.
comment:5 by , 13 years ago
I moved the test_sqlite settings file issue to another ticket (#18163) to avoid complicating this ticket with the design decision needed there.
I wonder if it would be a good idea to have "TEST_PASSWORD_HASHER" setting. This setting would move one of the existing PASSWORD_HASHERS to the top of the PASSWORD_HASHERS list.
comment:6 by , 13 years ago
Cc: | added |
---|
comment:7 by , 13 years ago
Cc: | added |
---|
comment:8 by , 13 years ago
I wonder if having a dummy hasher would further improve test speeds.
I don't expect the time taken by the MD5 hasher to be significant. PBKDF2 is slow because it hashes the password thousands of times. MD5 hashes it only once.
I wonder if it would be a good idea to have "TEST_PASSWORD_HASHER" setting.
Not another setting please :)
comment:9 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:10 by , 12 years ago
Big +1 on this, but it may be worth mentioning that if you have fixtures generated with a different password hasher you'll get errors if you don't include that hasher. Same speed up can be gained just by putting the MD5 hasher at the top of your existing setting. Obviously we shouldn't be using fixtures but...
comment:12 by , 12 years ago
Note that you CAN'T do this for just one test using @override_settings, because PREFERRED_HASHER is initialized once the first time get_hasher() is called. Ugh.
Workaround:
@override_settings(PASSWORD_HASHERS=( 'django.contrib.auth.hashers.SHA1PasswordHasher', 'django.contrib.auth.hashers.BCryptPasswordHasher', )) def test_whatever(self): import django.contrib.auth.hashers django.contrib.auth.hashers.PREFERRED_HASHER = None ...
To make it clear: in my case the cause of 2x slowdown seems to be user creation, not user authentication.