当前位置: 首页 > 面试题库 >

如何在Flask-Login中实现user_loader回调

罗祺
2023-03-14
问题内容

我正在尝试使用Flask和Flask-Login扩展在Flask应用中实现用户身份验证。目的是从数据库中提取用户帐户信息,然后登录用户,但我陷入了困境。但是,我将其范围缩小到Flask-Login行为的特定部分。

根据Flask-Login文档,我需要创建一个user_loader“回调”函数。此功能的实际目的和实现让我困惑了几天:

你将需要提供一个user_loader回调。此回调用于从会话中存储的用户ID重新加载用户对象。它应该采用用户的Unicode ID,并返回相应的用户对象。例如:

@login_manager.user_loader
def load_user(userid):
return User.get(userid)
现在,假设我希望用户在表单中输入名称和密码,对照数据库进行检查,然后登录用户。数据库的东西工作正常,对我来说没问题。

该“回调”函数希望传递给用户ID#,并返回User对象(我正在从数据库中加载其内容)。但是我并没有真正理解应该做的事情,因为无论如何,用户ID都是从同一位置提取的。我可以“排序”以使回调工作,但它看起来杂乱无章/骇人听闻,它会用浏览器请求的每个资源访问数据库。我真的不想检查我的数据库以便在每次刷新页面时都下载favicon.ico,但是flask-login登录似乎正在强迫这样做。

如果不再次检查数据库,则无法从该函数返回User对象。在烧瓶路径中创建了用于登录的User对象/类,因此不在回调的范围之内。

我不知道的是如何将User对象传递到此回调函数中,而不必每次都访问数据库。或者,否则就想出如何以更有效的方式进行此操作的方法。我肯定缺少一些基本的东西,但是我已经盯着它看了几天,扔了各种各样的函数和方法,没有任何结果。

以下是我的测试代码中的相关片段。用户类:

class UserClass(UserMixin):
     def __init__(self, name, id, active=True):
          self.name = name
          self.id = id
          self.active = active

     def is_active(self):
          return self.active

我将用户对象返回到Flask-Login的user_loader回调函数的函数:

def check_db(userid):

     # query database (again), just so we can pass an object to the callback
     db_check = users_collection.find_one({ 'userid' : userid })
     UserObject = UserClass(db_check['username'], userid, active=True)
     if userObject.id == userid:
          return UserObject
     else:
          return None

我不完全理解的“回调”(必须返回User对象,该对象是从数据库中提取后创建的):

@login_manager.user_loader
def load_user(id):
     return check_db(id)

登录路径:

@app.route("/login", methods=["GET", "POST"])
def login():
     if request.method == "POST" and "username" in request.form:
          username = request.form["username"]

          # check MongoDB for the existence of the entered username
          db_result = users_collection.find_one({ 'username' : username })

          result_id = int(db_result['userid'])

          # create User object/instance
          User = UserClass(db_result['username'], result_id, active=True)

          # if username entered matches database, log user in
          if username == db_result['username']:
               # log user in, 
               login_user(User)
               return url_for("index"))
          else:
               flash("Invalid username.")
      else:
           flash(u"Invalid login.")
      return render_template("login.html")

我的代码“ kinda”可以工作,我可以登录和注销,但是正如我所说,它必须访问数据库中的几乎所有内容,因为我必须在其他名称空间/作用域的其余地方为回调函数提供一个User对象。登录操作发生。我很确定自己做错了,但我不知道怎么做。

flask-login提供的示例代码以这种方式执行此操作,但这仅适用,因为它是从全局硬编码字典中拉出User对象,而不是像数据库这样的实际情况(在该场景中必须检查DB并用户输入用户登录凭据后创建的用户对象。而且我似乎找不到其他示例代码来说明如何通过flask-login使用数据库。

这里缺少什么?


问题答案:

你将需要在每次请求时从数据库加载用户对象。达到此要求的最强烈原因是Flask-Login每次都会检查身份验证令牌以确保其连续有效性。该令牌的计算可能需要将参数存储在用户对象上。

例如,假设一个用户有两个并发会话。在其中之一中,用户更改其密码。在随后的请求中,必须注销该第二个会话的用户,并强制其重新登录,以确保你的应用程序安全。考虑一下第二次会话被盗的情况,因为你的用户忘记了注销计算机-你希望更改密码以立即解决这种情况。你可能还希望使管理员能够将用户踢出去。

为了使这种强制注销发生,存储在cookie中的身份验证令牌必须:1)部分基于密码或每次设置新密码时都会更改的其他内容;2)在运行任何视图之前,请对照存储在数据库中的用户对象的最新已知属性进行检查。



 类似资料:
  • dash-flask-login This is an example of Flask-login implementation on top of a Dash application for users authentication. The example comes with users authentication through a sqlite3 database, however

  • 问题内容: 如何获取烧瓶上的复选框是否已选中我正在使用Flask开发服务器环境使用Flask,Gevent和Web套接字进行项目。我用过。这里 如何获得每个连接的唯一会话ID? 我想将其存储在数据库中,并在客户端断开连接后将其删除。 如何获得活动连接总数 问题答案: 没有会话ID。 Flask中的会话只是Cookie的包装。你保存在上面的内容经过数字签名,并以cookie的形式发送给客户端。当你发

  • Flask-Login 为 Flask 提供了用户会话管理。它处理了日常的登入,登出并且长时间记住用户的会话。 它会: 在会话中存储当前活跃的用户 ID,让你能够自由地登入和登出。 让你限制登入(或者登出)用户可以访问的视图。 处理让人棘手的 “记住我” 功能。 帮助你保护用户会话免遭 cookie 被盗的牵连。 可以与以后可能使用的 Flask-Principal 或其它认证扩展集成。 但是,它

  • 问题内容: 回调如何用PHP编写? 问题答案: 该手册可互换地使用术语“回调”和“可调用”,但是,“回调”传统上是指充当函数指针的字符串或数组值,并引用函数或类方法以供将来调用。自PHP 4以来,已经允许使用函数式编程的某些元素。 通常,这是使用可调用值的安全方法: 现代PHP版本允许上面的前三种格式直接作为调用。并支持以上所有内容。 注释/注意事项: 如果函数/类已命名空间,则字符串必须包含标准

  • 问题内容: 我正在编写一个具有多个充当用户的类的应用程序(例如,学校帐户和员工帐户)。我正在尝试使用Flask- Login简化操作,但是我不太确定如何做到这一点,因此当用户登录时,我可以让我的应用检查用户名是否属于School帐户或职员帐户,然后正确登录。 我知道如何找出它属于哪种 类型 的帐户(因为所有用户名都必须是唯一的)。但是之后,我不确定如何告诉应用程序我希望它登录该特定用户。 现在,我

  • 问题内容: 我试图允许用户使用他们的帐户通过单独的Web服务登录我的Flask应用。我可以联系此Web服务的api并接收安全令牌。如何使用此令牌对用户进行身份验证,以便他们可以访问受限视图? 我不需要将用户保存到我自己的数据库中。我只想验证他们的会话。我相信可以使用Flask- Security和@auth_token_required装饰器完成此操作,但是文档不是很详细,我不确定如何实现。 编辑