Flask-WTForms login validation

Django, Flask, Bottle, WSGI, CGI…
Antworten
JohnSnock
User
Beiträge: 15
Registriert: Mittwoch 11. August 2021, 19:44

Hi,

I created a login form with Flask-WTForms:

Code: Alles auswählen

class LoginForm(FlaskForm):

    legend = 'Anmelden'

    email = StringField(
        'E-Mail',
        validators=[
            DataRequired(message=data_required_message),
            Email(message='Keine gültige E-Mail Adresse.'),
            validate_login
        ]
    )

    password = PasswordField(
        'Passwort',
        validators=[
            DataRequired(message=data_required_message),
            validate_login
        ]
    )

    remember = BooleanField('Angemeldet bleiben')
    submit = SubmitField('Anmelden')
And to validate the login credentials (and show error message and styles in the form) I've created the following validator function (outside the LoginForm class):

Code: Alles auswählen

def validate_login(form, field):
    user = User.query.filter_by(email=form.email.data).first()
    if not user:
        raise ValidationError('E-Mail Adresse oder Passwort falsch.')
    elif not bcrypt.check_password_hash(user.password, form.password.data):
        raise ValidationError('E-Mail Adresse oder Passwort falsch.')
In my login route I have the code that actually logs the user in:

Code: Alles auswählen

if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user and bcrypt.check_password_hash(user.password, form.password.data):
            login_user(user, remember=form.remember.data)
In the login process I do 3 db requests:
- 1. calling validate_login for the email field
- 2. calling validate_login for the password field
- 3. actually logging the user in

This seems like bad practise.
I definitely want to show the error message on both email an password fields so the user doesn't know wheter a e-mail exists in the system or not.
Do you have any ideas how this could be improved? Or should I just leave it as it is? It works as intended.
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Berechne den Hash des übermittelten Passworts und prüfe dann mit einem einfachen Select ob in der User-Tabelle der Benutzer mit der E-Mail-Adresse und dem Password-Hash existiert.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@sparrow: in der Datenbank stehen gesalzene Hashes.
Man fragt die Datenbank nach dem Nutzer und wenn der nicht existiert, dann nimmt man einen dummy-Hash, der beim Prüfen dann fehlschägt. So hat man immer den selben Codepfad.
Antworten