Flask-principal教程(auth + authr)

poc*_*chi 27 python authentication authorization flask

有人知道关于烧瓶原理的好教程吗?我正在尝试进行身份验证和授权(needRole和needIdentity),但我还没有得到任何结果.

我几乎肯定没有真正全面的教程 - 也许你们中的一些人有一些时间在他们手上,并希望发布一个教程作为答案?我真的决心用烧瓶代替django,但需要解决这个问题.

小智 51

我知道这个问题有点陈旧,但是几天前我一直在寻找同样的东西,所以希望这将有助于未来的某些人...

一个好的起点是Flask-Principal的github回购.

我在使用Flask-Principal(FP)方面遇到了一些麻烦.如果您不熟悉装饰器,上下文管理器信号,您可能需要在使用FP之前稍微研究它们.

Flask基于名为Blinker的包注册信号.如果您没有Blinker,Flask仍会允许您声明信号,但他们不会做任何事情.要了解我的意思,请查看Flask的signals.py源代码.

那为什么这对FP来说很重要?好吧,事实证明FP使用信号来注册和更新身份.特别:

  1. identity_loaded:当调用此信号时,我们知道为用户创建一个标识对象.(它叫做 via Principal._set_thread_identity())

  2. 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)
Run Code Online (Sandbox Code Playgroud)

回到如何调用信号的问题.在Blinker中,当我们调用send()信号对象时,执行信号处理程序.所以对于我们的test信号,语法只是:

test.send()
Run Code Online (Sandbox Code Playgroud)

何时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)) 
Run Code Online (Sandbox Code Playgroud)

但是,如果我们使用装饰器为我们做这件事,我们可以简化设置信号.再次假装我已经设置了我的测试信号但没有连接它.我们可以做的:

@test.connect
def func_we_want_to_execute_when_signal_is_called():
    return stuff
Run Code Online (Sandbox Code Playgroud)

上面的代码所做的实际上是设置我们想要在发送测试信号时执行的功能.希望现在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
Run Code Online (Sandbox Code Playgroud)

所以你可以看到信号确实推动了身份过程.如果您正在寻找任何类型的授权方式,角色和权限实际上是(更容易)事后的想法.

对我来说,围绕信号缠绕是最难的部分; 我希望这对其他人也有帮助.但我真的很鼓励你仔细阅读我上面为Flask-Principal链接的源代码; 它可能是理解正在发生的事情的最佳方式.


agf*_*agf 6

那里唯一一个似乎就是这篇博文.

项目的网站是一个(非常简短的)教程,然后是完整的API文档.你的问题表明你已经看过了.

您可能也对提供会话管理的flask-login感兴趣,并且链接的博客文章也对此进行了介绍.

这里的任何人都不太可能有这方面的经验(以及分享详细信息的时间),但我只是为了一个教程答案.


jet*_*com 5

出于某种原因,烧瓶原理的例子非常少.我个人发现Flask-Principal文档一开始就很神秘.一旦我浏览了源代码,一切似乎都更好地适应了.

受到我能够找到的这两个链接的启发,在这里这里,我汇集了一个简单的例子,使用flask-login,flask-principal和blueprints

https://github.com/shankararul/flask-login-principal

我尽力在这里解释这篇文章.如果您有任何反馈,请告诉我,我可以修改/更新帖子

https://medium.com/@shankararul/a-shot-at-demystifying-flask-principal-dda5aaeb6bc6