4

This is most probably a stupid question, but still I can't find an answer.

Documentation for Flask-Security says:

If there are only certain times you need to require that your user is logged in, you can do so with:

if not current_user.is_authenticated:
  return current_app.login_manager.unauthorized()

But it gives no clue where this "current_user" variable shall come from. Not surprisingly I get a "NameError: global name 'current_user' is not defined" when I try to use it in my application source code.

Weird thing is that, when I use the variable in my HTML template, render_template function somehow completes without an error.

So, the question is, how can I use "current_user" variable in my application and how does the template engine "know" about it if my app doesn't?

AlexVB
  • 217
  • 4
  • 11

1 Answers1

4

You need to import current_user.

from flask_login import current_user

As far as where it comes from - it comes from a different package, flask-login:

#: A proxy for the current user. If no user is logged in, this will be an
#: anonymous user
current_user = LocalProxy(lambda: _get_user())
Bahrom
  • 4,752
  • 32
  • 41
  • [Miguel Grinberg also recommends putting a copy of current_user into `g.user`.](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins) – Bahrom Nov 06 '17 at 20:36
  • It did the thing, thank you. Do you also know how the template render engine get's this object? – AlexVB Nov 06 '17 at 20:36
  • @AlexVB I think it grabs it from the `context` [here](https://github.com/pallets/flask/blob/470112dd6e708a18eb4ec1daa10c4ea276620dbf/flask/templating.py#L121). I'm not very familiar with templating, but it should be pretty straightforward to debug/step through the code. My guess is that something populates it in the context and templating.py just retrieves it from there. – Bahrom Nov 06 '17 at 20:43
  • 1
    Probably Flask-Security injects the variable into Jinja context as Flask itself does with other variables (http://flask.pocoo.org/docs/0.12/templating/), but they could have written about that explicitly. – AlexVB Nov 06 '17 at 21:19
  • And, btw, one can import **current_user** from **flask-security** too, and that perhaps is better when using this package. – AlexVB Nov 06 '17 at 21:24
  • You could, but it might just keep the imports more organized if you're only interacting with the `flask_login` package in the codebase. I'm not sure what the convention is in this case, but from what I gather you're relying on `flask_login`, which relies on `flask-security`. If `flask_login` changed the implementation and defined their own version of `current_user`, you'd have to update your code. Of course, if you're already directly working with `flask-security`, you should import it from `flask-security`. – Bahrom Nov 06 '17 at 21:35
  • 1
    I though it was the other way round: `flask-security` extends `flask-login`. – AlexVB Nov 06 '17 at 21:43
  • 1
    Ah, you are correct, sorry I mixed up the two package names. Yes, disregard my previous comments, import it from `flask-security`. – Bahrom Nov 06 '17 at 21:45
  • 1
    I've been struggling with this for an hour. Using flask-login does not say anywhere (that I can see) that `current_user` needs to be imported. Seeing this solved my issue `current_user is not defined` – Mote Zart Dec 31 '19 at 20:45