Flask-wtform 大小写敏感问题

Mer*_*oug 5 flask flask-sqlalchemy flask-wtforms

我有一个带有用户登录系统的烧瓶应用程序。我现在注意到一些与用于注册和登录网站的电子邮件地址区分大小写相关的问题。TL;DR 问题:如何使用 Flask 表单的小写字母来评估用户是否存在于我的数据库中?

例子

假设用户 John Smith 在该网站上注册了一个帐户。他使用 John.Smith@gmail.com 进行注册,然后使用 John.smith@gmail.com 进行登录。截至目前,该网站将把他们视为两个不同的用户。我希望这被视为同一用户。

在Python(我的强项)中,我只需获取str(form.email.data).lower()注册表单,然后将其写入数据库中的用户表。然后当有人尝试登录时我会做同样的事情。换句话说,我总是会考虑使用小写字母进行注册和登录。

但我很难在 Jinja 中实现这一点,尽管它与 Python 相似。

register.html 的电子邮件部分:

                <div class="form-group">
                    {{ form.email.label(class="form-control-label") }}
                    {% if form.email.errors %}
                        {{ form.email(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.email.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.email(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
Run Code Online (Sandbox Code Playgroud)

routes.py中的注册代码:

@app.route("/register", methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('home'))

    form = RegistrationForm()

    admins = ['admin@admin.com',
              'admin@admin.com']


    if form.validate_on_submit():

        new_user_email = form.email.data.lower() ###<-----NOTE THAT THIS IS LOWER CASE
        admin_test = True if new_user_email in admins else False
        invited_test = Invites.query.filter(Invites.invited_email == new_user_email).count()
        print(admin_test, invited_test)

        if (invited_test == 0) & (admin_test == False): # Not invited and not and admin --> REJECT
            flash(
                'Sorry but it looks like you were not invited. Please contact a current member for an invitation.',
                'warning')
        elif (invited_test > 0) | (admin_test == True): ## if they have been invited OR if they are admin
            hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')

            #create User object
            user = User(username=form.username.data.lower(), ###<----NOTE LOWER CASE
                        email=form.email.data.lower(), ###<----NOTE LOWER CASE
                        password=hashed_password)

            #write to db
            db.session.add(user)
            db.session.commit()

            #alert user
            flash('Welcome to. Enjoy the platform.', 'success')
            return redirect(url_for('login'))

        else:
            #Not invited condition
            flash('Sorry but it looks like you were not invited to __. Please contact a current member for an invitation.', 'warning')

    return render_template('register.html', title='Register', form=form)
Run Code Online (Sandbox Code Playgroud)

login.html 的电子邮件部分:

            <div class="form-group">
                {{ form.email.label(class="form-control-label") }}
                {% if form.email.errors %}
                    {{ form.email(class="form-control form-control-lg is-invalid") }}
                    <div class="invalid-feedback">
                        {% for error in form.email.errors %}
                            <span>{{ error }}</span>
                        {% endfor %}
                    </div>
                {% else %}
                    {{ form.email(class="form-control form-control-lg") }}
                {% endif %}
            </div>
Run Code Online (Sandbox Code Playgroud)

小智 1

您可以使用 python 的内置方法 lower() 轻松地完成此操作。

在此示例中,我使用 .lower() 将整个电子邮件地址设为小写。您也可以使用.upper(). 无论您选择哪一个,只要确保它在整个网站范围内保持一致即可。我正在使用 MongoDB,但如果您使用 SQLAlchemy,情况也是如此。当您捕获表单数据时,form.email.data您只需添加.lower()即可使其全部小写。

登录路线

@app.route('/login/', methods=['GET', 'POST'])
def login():
    """Login Route"""
    if current_user.is_authenticated:
        return redirect(url_for('home'))
    form = LoginForm()
    if form.validate_on_submit():
        user = Users.objects(email=form.email.data.lower()).first()
Run Code Online (Sandbox Code Playgroud)

报名路线

当用户在您的网站上注册时,您希望在将数据提交到数据库时进行注册。在注册路径中,我还在名字和姓氏字段上使用了 .title() (仅供参考,.title 将每件作品的第一个字母大写,所有其他字母将小写)。人们的手指很高兴,有时会输入 JoHN DOe 等。这样可以保持名字和姓氏不变。并且,在电子邮件地址上我使用了 .lower()。
@app.route('/register/', methods=['GET', 'POST'])
def register():
    """Registration Route"""
    if current_user.is_authenticated:
        return redirect(url_for('home'))
    form = RegistrationForm()
    if form.validate_on_submit():
        hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
        add_new_user = Users(fname=form.data['fname'].title(), lname=form.data['lname'].title(),
                             email=form.data['email'].lower(), password=hashed_password)
Run Code Online (Sandbox Code Playgroud)

希望有帮助:)