我知道这个问题有点老了,但几天前我一直在寻找同样的东西,所以希望这对未来的人有所帮助。 . .
the github repo for Flask-Principal 是一个不错的起点。
我在使用 Flask-Principal (FP) 时也遇到了一些问题。如果您是 decorators、context-managers 和 signals 的新手,您可能需要在使用 FP 之前对其进行一些研究。
Flask 基于名为Blinker 的包注册信号。如果您没有 Blinker,Flask 仍然允许您声明信号,但它们不会做任何事情。要了解我的意思,请查看 Flask 的 signals.py 的源代码。
那么为什么这对 FP 很重要?好吧,事实证明 FP 使用信号来注册和更新身份。具体来说:
identity_loaded:当这个信号被调用时,我们知道要为用户创建一个身份对象。 (通过Principal._set_thread_identity()调用)
identity_changed:当这个信号被调用时,我们知道要更新用户的身份。 (当它被调用时执行 Principal._on_identity_changed())
那么我所说的称为是什么意思?首先,我们需要知道信号是如何设置的。 Blinker 通过允许函数“订阅”信号来工作。因此,例如,Principal._on_identity_changed() 被设置为信号identity_changed 的订阅者。每当发送信号identity_changed 时,就会执行_on_identity_changed()。代码如下所示:
from blinker import signal
test = signal('test')
test.connect(func_we_want_to_execute_when_signal_is_called)
回到如何调用信号的问题。在 Blinker 中,当我们在信号对象上调用 send() 时,会执行信号处理程序。所以对于我们的test 信号,语法就是:
test.send()
当test.send() 被调用时func_we_want_to_execute_when_signal_is_called 将执行。希望 FP 文档中的这个示例现在更有意义:
def login_view(req):
username = req.form.get('username')
# Your authentication here.
# Notice our signal (identity_changed) is being called (identity_changed.send())
# What function is being called? Principal._on_identity_changed()
identity_changed.send(app, identity=Identity(username))
但是,如果我们使用装饰器为我们做这件事,我们可以简化设置信号。再次假装我已经设置了我的测试信号但还没有连接它。我们可以这样做:
@test.connect
def func_we_want_to_execute_when_signal_is_called():
return stuff
上面的代码所做的基本上是设置我们在发送测试信号时要执行的函数。希望现在 FP 文档中的以下代码有意义:
# We're setting up our signal (identity_loaded)
# to execute the function below (on_identity_loaded)
# when we call our signal (identity_loaded.send())
# which is called in Principal._set_thread_identity()
@identity_loaded.connect
def on_identity_loaded(sender, identity):
# Get the user information from the db
user = db.get(identity.name)
# Update the roles that a user can provide
for role in user.roles:
identity.provides.add(RoleNeed(role.name))
# Save the user somewhere so we only look it up once
identity.user = user
因此,您可以看到信号真正推动了身份识别过程。如果您正在寻找一种方法来进行任何类型的授权,那么角色和权限确实是(更容易)事后才想到的。
对我来说,将我的头绕在信号上是最难的部分;我希望这对其他人也有帮助。但我真的鼓励你通读我上面为 Flask-Principal 链接的源代码;这可能是了解正在发生的事情的最佳方式。