You can write your own authentication server to use raw passwords:
from django.contrib.auth import backends from django.contrib.auth.models import User class RawPasswordUser(User): class Meta: proxy = True def set_password(self, raw_password):
In the settings file:
AUTHENTICATION_BACKENDS = ( # ModelBackend from project_root/auth/backends.py 'auth.backends.ModelBackend', )
Now that you authenticate users in your views, you will get instances of RawPasswordUser . The same applies to login_required decorator, request.user will point to a proxy class.
See the documentation for more details.
For Django 1.5+, there is also an option to replace the default user model with a user model, but to save existing users you will have to transfer them somehow, see this question .
In fact, you cannot save user passwords unchanged.
By default, Django stores passwords in the following format:
$ iteration algorithm $ salt $ hash
It means:
You cannot simply recover passwords from the hashes of the originals, since you do not have the originals.
You will also not be able to generate the same hash on the client side without knowing the salt. You can transfer it to the client side, but salt should be a secret, so it is unreasonable to do this through an unencrypted channel.
The simplest solution that I see is to keep Djangoβs current behavior, as suggested by Tadeck in the comments, add hashing to the client side and force users to change their passwords.
Well, this is not quite a solution, because an attacker can intercept digested passwords and use them directly, but you mentioned this in your question update. Since you don't really care about security, you can also check public key encryption in JavaScript.
Another solution Tadeck offers is to use an OAuth-like service, which might look something like this:
def index(request): access_token = request.REQUEST.get('token', None) if not access_token: return redirect('login')
An attacker can still intercept an access token, but it is slightly better than intercepting a password hash.