Anybody know of a good tutorial about flask-principal? I’m trying to do authentication and authorization (needRole and needIdentity) and I haven’t gotten anywhere.
I am almost sure there’s no really comprehensive tutorial — maybe some of you has some time on their hands and would like to post a tutorial-as-answer? I’m REALLY determined to use flask instead of django but need to fix this.
I know this question is kind of old, but a couple of days ago I was looking for the same thing so hopefully this will help someone in the future . . .
A good place to start is on the github repo for Flask-Principal.
I’ve had some trouble with Flask-Principal (FP) too. If you’re new to decorators, context-managers, and signals you’ll probably want to research them a little before using FP.
Flask registers signals based on a package called Blinker. If you don’t have Blinker, Flask will still allow you to declare signals however they won’t do anything. To see what I mean, have a look in the source for Flask’s signals.py.
So why does this matter for FP? Well, it turns out that FP uses signals to register and update identities. Specifically:
identity_loaded: When this signal is called, we know to create an identity object for the user. (It’s called viaPrincipal._set_thread_identity())identity_changed: When this signal is called, we know to update the user’s identity. (When it’s called it executesPrincipal._on_identity_changed())So what do I mean by called? First, we need to know how signals are set up. Blinker works by allowing functions to “subscribe” to signals. So, for example,
Principal._on_identity_changed()is set up as a subscriber for the signalidentity_changed. Whenever the signalidentity_changedis sent, _on_identity_changed() is executed. The code looks like this:Back to the question of how signals are called. In Blinker, signals handlers are executed when we call
send()on the signal object. So for ourtestsignal, the syntax is just:When
test.send()is calledfunc_we_want_to_execute_when_signal_is_calledwill execute. Hopefully this example in the FP documentation makes a bit more sense now:However we can simplify setting up signals if we use a decorator to do it for us. Pretend again that I’ve set up my test signal but haven’t connected it. We can do:
What the above code does is essentially sets up the function we want to execute when our test signal is sent. Hopefully now the following code from the FP documentation makes sense:
So you can see that signals really drive the identity process. Roles and permissions are really an (easier) afterthought if you’re looking for a way to do authorization of any kind.
For me, wrapping my head around signals was the hardest part; I hope this was helpful for someone else, too. But I’d really encourage you to read through the source code I’ve linked above for Flask-Principal; it is probably going to be the best way to understand what is going on.