Comments (5)
Right on. Thanks for catching this!
from flask-principal.
Thanks for addressing my comment, however I'm a little surprised (and stumped) at the fix. I expected a simple change to the documentation, but instead it looks like you tried to make the order of flask plugins not matter.
I'm still digesting what exactly changed here (and I noticed this issue on a test server, so I haven't had time to look at it on a dev server yet), but Flask-Login 0.2.9 is creating an infinite loop:
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/share/foo/lib/foo/bootstrap.py", line 69, in load_user
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] identity_changed.send(app, identity=Identity(user.id))
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/blinker/base.py", line 267, in send
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] for receiver in self.receivers_for(sender)]
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/flask_principal.py", line 469, in _on_identity_changed
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] self.set_identity(identity)
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/flask_principal.py", line 418, in set_identity
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] self._set_thread_identity(identity)
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/flask_principal.py", line 463, in _set_thread_identity
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] identity=identity)
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/blinker/base.py", line 267, in send
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] for receiver in self.receivers_for(sender)]
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/share/foo/lib/foo/views/user.py", line 196, in on_identity_loaded
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] user = current_user._get_current_object()
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 297, in _get_current_object
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] return self.__local()
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/flask_login.py", line 46, in <lambda>
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] current_user = LocalProxy(lambda: _get_user())
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/flask_login.py", line 768, in _get_user
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] current_app.login_manager._load_user()
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/flask_login.py", line 348, in _load_user
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] return self.reload_user()
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/local/lib/python2.7/dist-packages/flask_login.py", line 312, in reload_user
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] user = self.user_callback(user_id)
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] File "/usr/share/foo/lib/foo/bootstrap.py", line 69, in load_user
[Mon Feb 10 19:20:15 2014] [error] [client 4.31.164.110] identity_changed.send(app, identity=Identity(user.id))
You can see that load_user() ends up calling... load_user(). On my test server, this repeats until I get a RuntimeError: maximum recursion depth exceeded
.
This is a new test server, so it took me quite a while to figure out what was going on. (I thought I had botched some step of the deployment process.) Eventually I tried using pip to remove Flask-Login 0.2.9 and replace it with 0.2.7 instead. Boom, problem fixed.
I will post back when I have more details, but my gut reaction is that the documentation still doesn't match the reality of what Flask-Login is actually doing.
from flask-principal.
I was having trouble with this for a while as well. Because I don't want to use the session for user login in a REST api, I can't call login_user
from Flask-Login because that tries to set a session cookie. Thus, the current_user
is unset until after load_user_from_request
returns so I can't call principal.set_identity
from inside the request loader without triggering the recursive loop. I solved the issue by adding an intermediate signal callback to catch the user_loaded_from_request
signal which sets the identity:
@login_manager.request_loader
def load_user_from_request(request):
user = get_user(request)
return user
@user_loaded_from_request.connect
def on_user_loaded_from_request(sender, user):
principal.set_identity(Identity(user.id))
@identity_loaded.connect
def on_identity_loaded(sender, identity):
identity.user = current_user
identity.provides.add(UserNeed(current_user.id))
# Etc...
It would be nice if there was a way to configure Flask-Login to not use the session at all.
from flask-principal.
Thanks @joshfriend for your example. I've been trying to tie Flask-Login/Flask-Principal together for a REST API yet I couldn't get the on_identity_loaded
method to work if I attempt anything with current_user
, I realise now this causes some sort of recursive loop. 👍
from flask-principal.
this causes some sort of recursive loop.
Yes. You cannot use current_user
inside login_manager.request_loader
because the value that the current_user
proxy references is not set until a value is returned from the request_loader
. Referencing current_user
before it is set causes flask-login to try to load the user from the request by calling request_loader
and... 💥 💥 💥
from flask-principal.
Related Issues (20)
- Errors in the examples provided by the docs induced by latest changes HOT 3
- Add documentation for using with flask-jwt HOT 6
- Mongo based sessions do not allow dots as key names HOT 1
- Typo in docs
- Small mistake in test_principal.py
- Update Flask-Login example to use Signals
- Intersection of required and provided needs is not sufficient HOT 6
- Is this library maintained? HOT 10
- Struggling with using `http_exception=` HOT 4
- Add classifiers for supported python versions HOT 1
- deque mutated during iteration
- Fixed per-role permissions HOT 1
- LICENSE file is missing on pypi HOT 2
- Make `use_sessions` and `skip_static` configurable
- is this project dead? HOT 13
- Issue with classes in sets
- skip_static only whitelists the app's static endpoint, not those from blueprints
- use mongoengine HOT 1
- Add Typing to Project HOT 2
- Simplifying permission handling
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flask-principal.