Enforcing password strength requirements with django.contrib.auth.views.password_change

jslatts picture jslatts · Mar 8, 2011 · Viewed 31.5k times · Source

We have a Django application that requires a specific level of password complexity. We currently enforce this via client-side JavaScript which can easily be defeated by someone who is appropriately motivated.

I cannot seem to find any specific information about setting up server-side password strength validation using the django contrib built in views. Before I go about re-inventing the wheel, is there a proper way to handle this requirement?

Answer

EMP picture EMP · Jun 15, 2011

I also went with a custom form for this. In urls.py specify your custom form:

(r'^change_password/$', 'django.contrib.auth.views.password_change',
     {'password_change_form': ValidatingPasswordChangeForm}),

Inherit from PasswordChangeForm and implement validation:

from django import forms
from django.contrib import auth

class ValidatingPasswordChangeForm(auth.forms.PasswordChangeForm):
    MIN_LENGTH = 8

    def clean_new_password1(self):
        password1 = self.cleaned_data.get('new_password1')

        # At least MIN_LENGTH long
        if len(password1) < self.MIN_LENGTH:
            raise forms.ValidationError("The new password must be at least %d characters long." % self.MIN_LENGTH)

        # At least one letter and one non-letter
        first_isalpha = password1[0].isalpha()
        if all(c.isalpha() == first_isalpha for c in password1):
            raise forms.ValidationError("The new password must contain at least one letter and at least one digit or" \
                                        " punctuation character.")

        # ... any other validation you want ...

        return password1