1

我将 Flask 与 SQLAlchemy 和 Flask-Login 一起使用。

我可以成功登录和注销注册用户。

我感到困惑的是,当我在登录页面上输入错误的密码时,我会返回登录页面并显示一条“欢迎用户@email.com”的闪烁消息,根据代码,我本以为会只有在我成功登录时才会出现。

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
        user = User.query.filter_by(email=form.email.data).first()
        if form.validate_on_submit():
            if user and check_password_hash(user.password, form.password.data):
                session['user_id'] = user.id
                flash('Welcome %s' % user.email)
                return redirect(url_for('dashboard'))
            else:
                flash('Wrong email or password')
                return render_template("login.html", form=form)
        flash('The email or password is wrong.')

    return render_template("login.html", form=form)

编辑:感谢 Tigra,这就是我最终的结果。

views.py

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    user = User.query.filter_by(email=form.email.data).first()
    if request.method == "POST":
        if form.validate():
            # the session can't be modified as it's signed, 
            # so it's a safe place to store the user
            session['user_id'] = user.id
            flash('Welcome %s' % user.email)
            return redirect(url_for('dashboard'))
        else:
            flash('Wrong email or password')
            return render_template("login.html", form=form)
    return render_template("login.html", form=form)

forms.py

from models import User
from werkzeug import check_password_hash

class LoginForm(Form):
    email = TextField('email', validators = [Required(), Email()])
    password = PasswordField('password', validators = [Required()])
    remember_me = BooleanField('remember_me', default = False)

    def __init__(self, *args, **kwargs):
        Form.__init__(self, *args, **kwargs)
        self.user = None

    def validate(self):
        rv = Form.validate(self)
        if not rv:
            return False

        user = User.query.filter_by(email=self.email.data).first()
        if user is None:
            self.email.errors.append('Unknown username')
            return False

        if not check_password_hash(user.password,self.password.data):
            self.password.errors.append('Invalid password')
            return False

        self.user = user
        return True
4

1 回答 1

3

你有两个问题:

1)您不应该在表单验证后进行这样的检查(登录名/密码)。它应该在表单本身内部定义,阅读关于 wtforms 的自定义验证器

2)另外,请确保您呈现的格式是真实的,因为您至少在呈现的格式上有错误:

form = LoginForm()
    user = User.query.filter_by(email=form.email.data).first()

所以不能确定没有更多。
另外,您的 passcheck 功能来自 werzkeug.security?

至于表单自定义验证,有一个例子:
使用这种方法实际验证失败,而不是额外检查

class LoginForm(SafeForm):
   email=TextField(__("E-Mail"),validators=[Required()])
   password=PasswordField(__("Password"),validators=[Required()])
   submit=SubmitField(__("Login"))

   def __init__(self,*k,**kk):
      self._user=None #for internal user storing
      super(LoginForm,self).__init__(*k,**kk)

   def validate(self):
       self._user=User.query.filter(User.email==self.email.data).first()
       return super(LoginForm,self).validate()

   def validate_email(self,field):
       if self._user is None:
           raise ValidationError(_("E-Mail not recognized"))


   def validate_password(self,field):
       if self._user is None:
           raise ValidationError() #just to be sure
       if not self._user.validate_password(self.password.data): #passcheck embedded into user model
           raise ValidationError(_("Password incorrect"))
于 2013-05-02T11:33:45.917 回答