Класс usermixin для входа в Flask с MongoDB - PullRequest
0 голосов
/ 05 марта 2019

Я работаю, чтобы попытаться создать метод входа в систему некоторое время.Я использую приложение Flask, и оно работает хорошо.Все это работает локально на моей машине.В настоящее время я использую pymongo и MongoClient для подключения к БД.Это все работает хорошо, и я хотел бы не менять это, если это возможно.

Я пытаюсь использовать Flask-Login для создания users класса, используя usermixin.Это где я был крайне неудачным.Я пробовал несколько разных вещей, и моя проблема заключается в том, как извлечь данные из моей БД.Я делал это ранее с базой данных SQL, но для этого проекта я явно хочу использовать MongoDB.Это учебник, которому я пытался следовать, но мне сложно все понять, потому что он не очень хорошо объясняет, что делает каждая строка.

https://medium.com/@dmitryrastorguev/basic-user-authentication-login-for-flask-using-mongoengine-and-wtforms-922e64ef87fe

Это мое соединение с моей БД: client = MongoClient('mongodb://localhost:27017')

, и это мой текущий класс пользователей, который у меня не работает и где мне нужнопомощь.

class User(UserMixin):

  def __init__(self, username, password_hash):
    self.username = username
    self.password_hash = password_hash

  def check_password(self, password):
    return check_password_hash(self.password_hash, password)

  def get_id(self):
    return self.username

@login_manager.user_loader
def load_user(user_id):
    return User.objects(pk=user_id).first()

Тогда моя последняя часть - это форма входа в систему:

@app.route('/login', methods=["GET" , "POST"])
def login():
  if request.method == "GET":
    return render_template("login.html", error=False)
  if request.method == "POST":
    check_user = request.form["username"]
    if check_user:
      if check_password_hash(check_user['password'], request.form["password"]):
        login_user(check_user)
        return redirect(url_for('index'))

Я знаю, что в этом руководстве используется MongoEngine, который я не использую, или пока не пользуюсь, но некоторая помощь здесьили как заставить работать этот код выше или как его адаптировать было бы здорово.Когда я запускаю этот код, я не получаю никаких ошибок, он просто не работает.Мой тест состоит в том, что я пытаюсь войти в систему, а затем пытаюсь перейти на страницу выхода, которая загружается следующим кодом:

@app.route("/logout")
@login_required
def logout():
  logout_user()
  return redirect(url_for('index'))

Когда я это делаю, он не загружает страницу, и я получаю и неавторизованную страницу.уведомление.Таким образом я знаю, что мой код не работает.Наконец, у меня есть все шаблоны в статической папке.

Заранее спасибо за помощь и, пожалуйста, если что-то не ясно, спросите, и я постараюсь добавить больше деталей.Чем конкретнее, тем лучше я смогу помочь.

ОБНОВЛЕНИЕ:

Я понял, что, вероятно, также важно описать, как структурирована моя БД, чтобы убедиться, что я обращаюсь к ней правильно, потому что это важный моментгде у меня проблемы.У меня есть БД с моей коллекцией под названием Users , и она структурирована так, что каждый документ представляет собой отдельную запись пользователя, например:

{
    "_id" : 1,
    "Reset" : false,
    "FirstName" : "John",
    "LastName" : "Doe",
    "Email" : "JohnDoe@gmail.com",
    "Username" : "",
    "admin" : false,
    "Pass" : "[hashed_password]"
}
{
    "_id" : 2,
    "Reset" : true,
    "FirstName" : "Jane",
    "LastName" : "Smith",
    "Email" : "JaneSmith@hotmail.com",
    "Username" : "Jane",
    "admin" : false,
    "Pass" : "[hashed_password]"
}
{
    "_id" : 3,
    "Reset" : true,
    "FirstName" : "Gary",
    "LastName" : "Bettman",
    "Email" : "GBettman@yahoo.com",
    "Username" : "HockeyGuy",
    "admin" : false,
    "Pass" : "[hashed_password]"
}

1 Ответ

0 голосов
/ 05 марта 2019

Что нужно знать о Flask-login: это расширение работает с пользовательской моделью приложения и ожидает, что в нем будут реализованы определенные свойства и методы.(источник: https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins).

Ниже перечислены четыре обязательных элемента:

  • is_authenticated: свойство True, если пользователь имеет действительные учетные данные, или False в противном случае.

  • is_active: свойство, которое имеет значение True, если учетная запись пользователя активна, или False, в противном случае.

  • is_anonymous: свойствоFalse для обычных пользователей и True для специального анонимного пользователя.

  • get_id(): метод, который возвращает уникальный идентификатор пользователя в виде строки

К сожалению, все примеры в официальной документации и на превосходном блоге Мигеля Гринберга используют SQLAlchemy. Хорошие новости, его можно реализовать с помощью Pymongo ...

РЕШЕНИЕ

  1. rout.py

    from flask import Flask
    from flask_pymongo import PyMongo
    from flask_login import LoginManager
    from flask import render_template, url_for, request, flash
    from app.forms import Login
    from flask import request
    from werkzeug.urls import url_parse
    from werkzeug.security import generate_password_hash, check_password_hash
    from flask_login import current_user, login_user, logout_user, login_required
    
    mongo = PyMongo(app)
    login = LoginManager(app)
    login.login_view = 'login'
    
    class User:
        def __init__(self, username):
            self.username = username
    
        @staticmethod
        def is_authenticated():
            return True
    
        @staticmethod
        def is_active():
            return True
    
        @staticmethod
        def is_anonymous():
            return False
    
        def get_id(self):
            return self.username
    
        @staticmethod
        def check_password(password_hash, password):
            return check_password_hash(password_hash, password)
    
    
        @login.user_loader
        def load_user(username):
            u = mongo.db.Users.find_one({"Name": username})
            if not u:
                return None
            return User(username=u['Name'])
    
    
        @app.route('/login', methods=['GET', 'POST'])
        def login():
            if current_user.is_authenticated:
                return redirect(url_for('index'))
            form = Login()
            if form.validate_on_submit():
                user = mongo.db.Users.find_one({"Name": form.name.data})
                if user and User.check_password(user['Password'], form.password.data):
                    user_obj = User(username=user['Name'])
                    login_user(user_obj)
                    next_page = request.args.get('next')
                    if not next_page or url_parse(next_page).netloc != '':
                        next_page = url_for('index')
                    return redirect(next_page)
                else:
                    flash("Invalid username or password")
            return render_template('login.html', title='Sign In', form=form)
    
    
        @app.route('/logout')
        def logout():
            logout_user()
            return redirect(url_for('login'))
    
  2. form.py

    from flask_wtf import FlaskForm
    from wtforms import StringField, SubmitField, PasswordField
    from wtforms.validators import DataRequired
    
    
    class Login(FlaskForm):
        name = StringField('name' validators=[DataRequired()])
        password = PasswordField('Password', validators=[DataRequired()])
        login = SubmitField('Login')
    

Предполагается, что на стороне Mongodb имеется коллекция ( Users ), которая содержит некоторую информацию для входа в систему. Например:

{
  Name: [username],
  Password: [hashed_password]
} 

Для более подробного объяснения того, что делает каждая строка кода, я рекомендую вам обратиться к следующим ссылкам:

...