我正在尝试使用Flask和Flask-Login扩展名在Flask应用中实现用户身份验证。目的是从数据库中提取用户帐户信息,然后登录用户,但我陷入了困境。但是,我将其范围缩小到了Flask-Login行为的特定部分。
根据Flask-Login documentation,我需要创建一个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 does it this way提供的示例代码,但是仅能正常工作,因为它是从全局硬编码字典中拉出User对象,而不是像数据库这样的现实情况,在该场景中必须检查DB并创建User对象在用户输入其登录凭据后。而且我似乎找不到任何其他示例代码来说明如何通过flask-login使用数据库。
这里缺少什么?
参考方案
您将需要根据每个请求从数据库加载用户对象。该要求的最强烈原因是Flask-Login每次都会检查身份验证令牌,以确保其持续有效性。该令牌的计算可能需要将参数存储在用户对象上。
例如,假设一个用户有两个并发会话。在其中之一中,用户更改密码。在随后的请求中,必须注销第二个会话的用户,并强制重新登录,以确保您的应用程序安全。考虑一下第二次会话被盗的情况,因为您的用户忘记了退出计算机-您希望更改密码以立即解决这种情况。您可能还希望使管理员能够将用户赶出市场。
为了使这种强制注销发生,存储在cookie中的身份验证令牌必须:1)部分基于密码或每次设置新密码时都会更改的其他内容; 2)在运行任何视图之前,请对照存储在数据库中的用户对象的最新已知属性进行检查。
Python uuid4,如何限制唯一字符的长度 - python在Python中,我正在使用uuid4()方法创建唯一的字符集。但是我找不到将其限制为10或8个字符的方法。有什么办法吗?uuid4()ffc69c1b-9d87-4c19-8dac-c09ca857e3fc谢谢。 参考方案 尝试:x = uuid4() str(x)[:8] 输出:"ffc69c1b" Is there a way to…
Python-如何检查Redis服务器是否可用 - python我正在开发用于访问Redis Server的Python服务(类)。我想知道如何检查Redis Server是否正在运行。而且如果某种原因我无法连接到它。这是我的代码的一部分import redis rs = redis.Redis("localhost") print rs 它打印以下内容<redis.client.Redis o…
Python-crontab模块 - python我正在尝试在Linux OS(CentOS 7)上使用Python-crontab模块我的配置文件如下:{ "ossConfigurationData": { "work1": [ { "cronInterval": "0 0 0 1 1 ?", "attribute&…
Python GPU资源利用 - python我有一个Python脚本在某些深度学习模型上运行推理。有什么办法可以找出GPU资源的利用率水平?例如,使用着色器,float16乘法器等。我似乎在网上找不到太多有关这些GPU资源的文档。谢谢! 参考方案 您可以尝试在像Renderdoc这样的GPU分析器中运行pyxthon应用程序。它将分析您的跑步情况。您将能够获得有关已使用资源,已用缓冲区,不同渲染状态上…
Python:图像处理可产生皱纹纸效果 - python也许很难描述我的问题。我正在寻找Python中的算法,以在带有某些文本的白色图像上创建皱纹纸效果。我的第一个尝试是在带有文字的图像上添加一些真实的皱纹纸图像(具有透明度)。看起来不错,但副作用是文本没有真正起皱。所以我正在寻找更好的解决方案,有什么想法吗?谢谢 参考方案 除了使用透明性之外,假设您有两张相同尺寸的图像,一张在皱纹纸上明亮,一张在白色背景上有深…