带有MongoDB的Flask-login usermixin类

问题描述 投票:0回答:1

我正在努力尝试建立一个登录方法一段时间了。我正在运行Flask应用程序,并且运行良好。它全部在我的机器上运行。目前,我正在使用pymongoMongoClient来连接数据库。这一切都运作良好,我想尽可能不改变它。

我正在尝试使用Flask-Login使用users创建一个usermixin类。这是我非常不成功的地方。我尝试了一些不同的东西,我的问题是如何从数据库中提取数据。我以前用SQL DB做过这个,但对于这个项目,我明确地想要使用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" : "[email protected]",
    "Username" : "",
    "admin" : false,
    "Pass" : "[hashed_password]"
}
{
    "_id" : 2,
    "Reset" : true,
    "FirstName" : "Jane",
    "LastName" : "Smith",
    "Email" : "[email protected]",
    "Username" : "Jane",
    "admin" : false,
    "Pass" : "[hashed_password]"
}
{
    "_id" : 3,
    "Reset" : true,
    "FirstName" : "Gary",
    "LastName" : "Bettman",
    "Email" : "[email protected]",
    "Username" : "HockeyGuy",
    "admin" : false,
    "Pass" : "[hashed_password]"
}
mongodb flask pymongo mongoengine
1个回答
1
投票

您需要了解的有关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():一种为用户返回字符串唯一标识符的方法

不幸的是,官方文档和Miguel Grinberg的优秀博客中的所有示例都使用SQLAlchemy。好消息,有可能用Pymongo实现它......

解决方案

  1. routes.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]
} 

有关每行代码的详细说明,建议您查阅以下链接:

© www.soinside.com 2019 - 2024. All rights reserved.