Flask Python Ошибка аутентификации при входе - PullRequest
0 голосов
/ 20 марта 2020

Я новичок в Python Flask. Когда я пытался создать простую страницу входа в систему и выхода из системы, я столкнулся с проблемой неудачной аутентификации (правильное имя пользователя с неправильным паролем может войти в систему). Я не был уверен, где это пойдет не так, потому что изначально все работало нормально. Кто-нибудь может просветить меня?

views.py

from flask import Blueprint, request, redirect, render_template, url_for
from flask_login import current_user, login_required, login_user

from . import db, login_manager
from .forms import LoginForm, RegistrationForm
from .models import WebUser

view = Blueprint("view", __name__)

@login_manager.user_loader
def load_user(username):
    user = WebUser.query.filter_by(username=username).first()
    return user or current_user

@view.route("/", methods=["GET", "POST"])
def render_login_page():
    form = LoginForm()
    if form.is_submitted():
        print("username entered:", form.username.data)
        print("password entered:", form.password.data)
    if form.validate_on_submit():
        user = WebUser.query.filter_by(username=form.username.data).first()
        if user:
            # TODO: You may want to verify if password is correct
            login_user(user)
            print(login_user(user))
            return redirect("/homepage")
    return render_template("index.html", form=form)

@view.route("/registration", methods=["GET", "POST"])
def render_registration_page():
    form = RegistrationForm()
    if form.validate_on_submit():
        username = form.username.data
        preferred_name = form.preferred_name.data
        password = form.password.data
        query = "SELECT * FROM web_user WHERE username = '{}'".format(username)
        exists_user = db.session.execute(query).fetchone()
        if exists_user:
            form.username.errors.append("{} is already in use.".format(username))
        else:
            query = "INSERT INTO web_user(username, preferred_name, password) VALUES ('{}', '{}', '{}')"\
                .format(username, preferred_name, password)
            db.session.execute(query)
            db.session.commit()
            return "You have successfully signed up!"
    return render_template("registration-simple.html", form=form)
    #form is passed in as a model

@view.route("/homepage", methods=["GET"])
@login_required
def render_homepage():
    return "<h1>Hello, {}!</h1>".format(current_user.preferred_name or current_user.username)

@view.route("/logout")
@login_required
def render_logout():
    logout_user()
    return render_template("index.html")

forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import InputRequired, ValidationError

def is_valid_name(form, field):
    if not all(map(lambda char: char.isalpha(), field.data)):
        raise ValidationError('This field should only contain alphabets')

def agrees_terms_and_conditions(form, field):
    if not field.data:
        raise ValidationError('You must agree to the terms and conditions to sign up')

class RegistrationForm(FlaskForm):
    username = StringField(
        label='Name',
        validators=[InputRequired(), is_valid_name],
        render_kw={'placeholder': 'Username', 'class': 'input100'}
    )
    preferred_name = StringField(
        label='Preferred name',
        validators=[is_valid_name],
        render_kw={'placeholder': 'Preferred name', 'class': 'input100'}
    )
    password = PasswordField(
        label='Password',
        validators=[InputRequired()],
        render_kw={'placeholder': 'Password', 'class': 'input100'}
    )

class LoginForm(FlaskForm):
    username = StringField(
        label='Name',
        validators=[InputRequired()],
        render_kw={'placeholder': 'Username', 'class': 'input100'}
    )
    password = PasswordField(
        label='Password',
        validators=[InputRequired()],
        render_kw={'placeholder': 'Password', 'class': 'input100'}
    )

models.py

from . import db    
class WebUser(db.Model):
    username = db.Column(db.String, primary_key=True)
    preferred_name = db.Column(db.String, nullable=True)
    password = db.Column(db.String, nullable=False)

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return self.username

страница входа. html

<body>

    <div class="limiter">
        <div class="container-login100" style="background-image: url('static/images/bg-01.jpg');">
            <div class="wrap-login100 p-t-30 p-b-50">
                <span class="login100-form-title p-b-41">
                    Food Delivery System
                </span>

                <form class="login100-form validate-form p-b-33 p-t-5">
                    {{ form.hidden_tag() }}

                    <div class="wrap-input100 validate-input" data-validate = "Enter username">
                        {{ form.username() }}
                        <span class="focus-input100" data-placeholder="&#xe82a;"></span>
                    </div>

                    <div class="wrap-input100 validate-input" data-validate="Enter password">
                        <!-- <input class="input100" type="password" name="pass" placeholder="Password"> -->
                        {{ form.password() }}
                        <span class="focus-input100" data-placeholder="&#xe80f;"></span>
                    </div>

                    <div class="container-login100-form-btn m-t-32">
                        <button class="login100-form-btn" formmethod="post">
                            Login
                        </button>
                    </div>
                    <br>
                    <p style="text-align: center;">New user? <a href="{{url_for('view.render_registration_page')}}" style="color: tomato;">Register</a></p>
                </form>
            </div>
        </div>
    </div>

1 Ответ

0 голосов
/ 20 марта 2020

Вот пример того, как вы можете реализовать механизм входа в систему:

views.py

from flask_login import current_user, login_required, login_user

@view.route("/", methods=["GET", "POST"])
def render_login_page():
    if current_user.is_authenticated:
        return redirect("/homepage")

    form = LoginForm()

    if form.validate_on_submit():
        user = WebUser.query.filter_by(username=form.username.data).first()
        if user is None or user.password != form.password.data:
            # password or user are incorrect then we redirect to the login page.
            return redirect('/')

        login_user(user)
        print(login_user(user))
        return redirect("/homepage")
    return render_template("index.html", form=form)

models.py

from . import db  
from flask_login import UserMixin

class WebUser(UserMixin, db.Model):
    username = db.Column(db.String, primary_key=True)
    preferred_name = db.Column(db.String, nullable=True)
    password = db.Column(db.String, nullable=False)

Обратите внимание, что я импортировал класс UserMixin модуля flask_login.

Расширение flask-login работает с пользовательской моделью приложения и ожидает реализации в ней определенных свойств и методов, таких как: is_authenticated, is_active, is_anonymous и get_id.

Для этого модуль предлагает класс mixin , называемый UserMixin, который содержит обобщенную реализацию c этих методов, которая подходит для большинства сценариев ios.

Так что вам не нужно определять их самостоятельно. Вы можете просто включить класс mixin в свою модель.

...