Question

I'm trying to create a registration form where a user enter's in a username/password combination.

I want the password to use MyPBKDF2 for password hashing.

I have hashers.py

from django.contrib.auth.hashers import PBKDF2PasswordHasher

    class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
        """
        A subclass of PBKDF2PasswordHasher that uses 100 times more iterations.
        """
        iterations = PBKDF2PasswordHasher.iterations * 100

settings.py

PASSWORD_HASHERS = (
    'MyApp.hashers.MyPBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
    'django.contrib.auth.hashers.CryptPasswordHasher',
)

views.py

def Registration(request):
    RegForm = RegistrationForm(request.POST or None)
    if request.method == 'POST':
        if RegForm.is_valid():

            clearUserName = RegForm.cleaned_data['userNm']   #set clean username
            hashpass = make_password(RegForm.cleaned_data['userPass'], None, 'pbkdf2_sha256')

            RegForm.save()
            try:
                return HttpResponseRedirect('/Newuser/?userNm=' + clearUserName)
            except:
                raise ValidationError(('Invalid request'), code='300')    ## [ TODO ]: add a custom error page here.
    else:
        RegForm = RegistrationForm()

        return render(request, 'Myapp/reuse/register.html', {
            'RegForm': RegForm 
        })

forms.py c

lass RegistrationForm(ModelForm):
    userPass = forms.CharField(widget=forms.PasswordInput, label='Password')
    class Meta:
        model = Client
        fields = ['userNm','userPass']


def clean_RegForm(self):
    cleanedUserName = self.cleaned_data.get('userNm')
    if Client.objects.filter(userNm=cleanedUserName).exists():
        errorMsg = u"Error occurred."
        raise ValidationError(errorMsg)
    else:
        return cleanedUserName

I'm getting the password submitting, but in plain text - which is no good.

What am I doing wrong here?

Was it helpful?

Solution

Well.. you're creating hashed password, but not saving it anywhere. And because you're saving form (which inherits from ModelForm), the password fields is saved straight from the password form field.

You can override save method and set hashpass as password. But I think the best practice here is to use UserCreationForm which handles password hashing for you (it will use the first password hasher from your list).

There are some examples here on SO, showing how to customize UserCreationForm, so search around.

Pseudo-code:

forms.py

from django.contrib.auth.forms import UserCreationForm


class RegisterForm(UserCreationForm):
    def __init__(self, *args, **kwargs):
        super(RegisterForm, self).__init__(*args, **kwargs)
        # do not require password confirmation
        del self.fields['password2']

views.py

def home(request):
    form = RegisterForm()

    if request.method == "POST":
        form = RegisterForm(request.POST)

        if form.is_valid():
            user = form.save()
            # redirect!

    return render(request, 'home.html', {
        'form': form
    })
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top