Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Embed URL


Subversion checkout URL

You can clone with
Download ZIP
Flask login with wtfoms validation
class LoginForm(flask_wtf.Form):
Validate login from
email_validator = [flask_wtf.Required()]
pwd_validator = [flask_wtf.Required(), flask_wtf.Length(2)]
email = flask_wtf.TextField(u'email', validators=email_validator)
password = flask_wtf.PasswordField(u'password', validators=pwd_validator)
submit = flask_wtf.SubmitField("Login")
def _get_user(self, email):
return mongo.db.users.find_one({'email': email})
def validate_email(self, field):
if not self._get_user(
raise flask_wtf.ValidationError("Invalid email")
def validate_password(self, field):
user = self._get_user(
if user and user[u'password'] !=
raise flask_wtf.ValidationError("Invalid password")
class Login(MethodView):
def __init__(self):
self.form = LoginForm()
def get(self):
return flask.render_template('login.html', login_form=self.form)
def post(self):
if self.form.validate():
flask.session['user'] =
flask.flash('You were logged in')
return flask.redirect(flask.url_for("index"))
return flask.render_template('login.html', login_form=self.form)
methods=['POST', 'GET'])

You cannot do this
def init(self):
self.form = LoginForm()

is out of the scope of working applicatoin contextg


There's a security concern with exposing specifically username is invalid or password is invalid(You solve half of the problem for mr hacker). In such cases it's better to say "username or password is invalid" without specifiing which one exactly.


I don't think exposing username matters that much:
1. Your project probably has public usernames anyway.
2. Usability suffers.


TextField has now been deprecated in favor of StringField in WTForms. I suggest updated line 8 accordingly to:
email = flask_wtf.StringField(u'email', validators=email_validator)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.