草庐IT

mongodb - Flask-login usermixin 类与 MongoDB

coder 2023-11-05 原文

一段时间以来,我一直在尝试构建登录方法。我正在运行 Flask 应用程序并且运行良好。这一切都在我的机器上本地运行。目前,我正在使用 pymongoMongoClient 连接到数据库。这一切都很好,如果可能的话,我不想改变它。

我正在尝试使用 Flask-Login 创建一个使用 usermixinusers 类。这是我非常不成功的地方。我尝试了一些不同的东西,我的问题是如何从我的数据库中提取数据。我以前使用 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" : "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]"
}

最佳答案

关于 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. 路由.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. 表单.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 端有一个包含一些登录信息的集合(用户)。例如:

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

为了进一步解释每行代码的作用,我建议您查阅以下链接:

关于mongodb - Flask-login usermixin 类与 MongoDB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54992412/

有关mongodb - Flask-login usermixin 类与 MongoDB的更多相关文章

  1. ruby-on-rails - Ruby 的文件类与 Rails 的 FileUtils - 2

    学习Ruby和Rails大约2周后,我发现自己经常使用File类来处理File.join、File.打开等。然后我遇到了File.copy的需求,却发现不存在这样的方法。再仔细一看,发现了Rails的FileUtils类,现在我有点困惑。当然有差异,但也有看似冗余的地方。在存在差异的地方,一个比另一个更受欢迎吗?为什么两者都存在(仅仅是为了处理Ruby核心类中的遗漏)?我只是想了解一下这些事情是如何协同工作或发生冲突的,以便我知道如何继续前进。谢谢。 最佳答案 FileUtils是Ruby核心API的一部分。它不是特定于Rails的

  2. ruby - 类与 Class.new,模块与 Module.new - 2

    class之间有什么区别?和Class.new&module和Module.new?我知道:Class.new/Module.new创建一个匿名class/module.当我们第一次将它分配给常量时,它变成了那个class的名称。/module.class/module自动执行此操作。当我们想要继承时,我们可以传递一个参数:Class.new(ancestor).当我们不指定祖先时,它被设置为Object.class使用此语法:classAClass.new返回object.classA返回nil.同样适用于module秒。我错过了什么吗? 最佳答案

  3. ruby - 模块的实例变量是否在类与 mixin 之间共享? - 2

    我想知道Ruby模块的实例变量在多个类中的行为如何“混合”它。我写了一个示例代码来测试它:#HereisamoduleIcreatedwithoneinstancevariableandtwoinstancemethods.moduleSharedVar@color='red'defchange_color(new_color)@color=new_colorenddefshow_colorputs@colorendendclassExample1includeSharedVardefinitialize(name)@name=nameendendclassExample2includ

  4. ruby-on-rails - 在一个 Rails 应用程序中使用 PostgreSQL 的 MongoDB - 2

    我可以在一个Rails应用程序中同时使用MongoDB和PostgreSQL吗?具体来说,我最终会想要使用像MongoHQ这样的东西。到目前为止,我未能在实验中进行这项工作。令我担心的是,MongoDB文档特别指出我必须禁用ActiveRecord。任何建议将不胜感激。 最佳答案 您无需禁用ActiveRecord即可使用MongoDB。查看Mongoid只需将gem加上任何模型与您现有的任何ActiveRecord模型一起添加。您应该注意到MongoHQ只是MongoDB的托管服务,可以与任何对象文档映射器(ODM)一起使用。更多

  5. ruby - 使用 mongodb/mongoid 运行时更改模型 - 2

    我必须在mongoid模型中添加几个字段,我知道MongoDB没有迁移,但如果我继续而不删除数据库,使rails完全“重新生成”数据库,它不会显示或使用新的领域!去这里最好的方法是什么?有比删除/重新打开mongodb更软的东西吗?提前致谢卢卡 最佳答案 一般来说,应该可以在运行时用新字段更新旧文档。MongoDB中不需要迁移。您可能想编写rake任务以使用新字段和默认值更新旧文档。您可以通过检查那些默认值为nil的新字段来找到这些文档。更新简单风格:如果您使用默认值定义一个新字段,只要您设置了一个新值,就应该始终使用该值:应用程序

  6. ruby-on-rails - 我如何从 Ruby 代码连接到 mongodb? - 2

    我如何从Ruby代码连接到mongodb? 最佳答案 首先,您必须安装MongoDbgem:geminstallmongo然后运行代码:require'rubygems'#notnecessaryforRuby1.9require'mongo'db=Mongo::Connection.new.db("mydb")#ORdb=Mongo::Connection.new("localhost").db("mydb")#ORdb=Mongo::Connection.new("localhost",27017).db("mydb")

  7. ruby - MongoDB:无法从 BSON 类型 EOO 转换为 Date - 2

    我正在尝试使用聚合框架(使用ruby​​)并像这样投影日期:db['requests'].aggregate([{"$project"=>{_id:0,method:'$method',user:'$user',year:{'$year'=>'$timestamp'}}}])文档是这样的:{_id:ObjectId("5177d7d7df26358289da7dfd"),timestamp:ISODate("2013-04-12T03:58:05+00:00"),method:"POST",status:"200",inputsize:"874",outputsize:"4981",u

  8. ruby - 在 Ruby 中从 MongoDB 中检索字段的子集 - 2

    我试图通过在Ruby中进行的查询从MongoDB获取字段的子集,但它似乎不起作用。它不返回任何结果这是ruby代码:coll.find("title"=>'Halo',:fields=>["title","isrc"])#thisdoesn'twork如果我删除字段散列,它会工作,返回包含所有字段的结果coll.find("title"=>'Halo')#thisworks查看mongodb控制台,第一个查询在mongodb服务器上结束,如下所示:{title:"Halo",fields:["title","isrc"]}如果我尝试从mongo客户端控制台进行查询,它会工作,我会得到结

  9. ruby-on-rails - Ruby 中的嵌套类与紧凑类 - 2

    从事初始Rails项目,并使用Rubocop分析代码风格。这让我质疑Ruby的嵌套类在Rails的上下文中究竟是如何工作的。例如,在我的引擎中,我有一个模型:#app/models/app_core/tenant.rbmoduleAppCoreclassTenant和一个Controller:#app/controllers/app_core/tenant/members_controller.rbmoduleAppCoreclassTenant::MembersController在模型的情况下,模块与路径相同,类名与文件名相同。在Controller的情况下,路径的第二部分“ten

  10. Ruby 类与结构 - 2

    我见过代码库使用Structs来包装类内的属性和行为。Ruby类和结构有什么区别?什么时候应该用一个代替另一个。? 最佳答案 来自Structdocs:AStructisaconvenientwaytobundleanumberofattributestogether,usingaccessormethods,withouthavingtowriteanexplicitclass.TheStructclassgeneratesnewsubclassesthatholdasetofmembersandtheirvalues.Forea

随机推荐