Search code examples
djangopasswordsdjango-authentication

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


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?


Solution

  • 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