13

I am using Flask-Security to set up user authentication for my app but I am struggling with getting the email address or ID of the currently logged in user so I can query a table with that particular users details. I've just using the standard code.

Another question here suggested the following but it didn't work:

my_user = current_user.get_id()

Standard code:

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_security import Security, SQLAlchemyUserDatastore, \
    UserMixin, RoleMixin, login_required

# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'

# Create database connection object
db = SQLAlchemy(app)

# Define models
roles_users = db.Table('roles_users',
        db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
        db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(255))

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))

# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)

# Create a user to test with
@app.before_first_request
def create_user():
    db.create_all()
    user_datastore.create_user(email='[email protected]', password='password')
    db.session.commit()

# Views
@app.route('/')
@login_required
def home():
    return render_template('index.html')

if __name__ == '__main__':
    app.run()

5 Answers 5

14

You can use flask_login.current_user object. Its class will be what you configured Flask-Security to use to handle your users management, e.g. User for code you included.

Sign up to request clarification or add additional context in comments.

4 Comments

Could you explain how I can print the current user to the terminal in the case of above? I have tried print(flask_login.current_user) and print(User.current_user) etc but cannot seem to get the current user using your method.
It's not 'my method'. It's an object built into flask_login module, which is automatically set up by Flask-Security. Did you import flask_login before trying to print out flask_login.current user?
I followed the flask-security quickstart, which recommended creating the User class in a models.py file. In my app.py file, I could import flask_login, then refer to flask_login.current_user.email as @Puchatek described. The current_user is an instance of the User class I defined in models.py.
Where do you import flask_login from? Ah I see it in another comment. It would be good to add this to your answer itself.
9

Michael was half right, the issue is that the standard code example does not import sessions and whilst flask-security does in the back end set the session, it's not available in your flask app. This code from Michael:

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        session['email'] = request.form['email']

Whilst correct in a standard app would likely break with flask-security or at least be unnecessary as flask-security completely takes control of the /login route and handles the form securely. The only two changes needed to the flask example app are:

Changing the flask import line to:

from flask import Flask, render_template, session

This is an example of getting the user id from the session:

@app.route('/dashboard')
@login_required
def dashboard():
    user_id = session["user_id"]
    return name

Hope this helps someone as it took me a while to get my head around..

1 Comment

If I wanted to add something to the session at login, other than just fresh and user_id (like username), what's the best way to do that? If I take the route, I break flask-security stuff.
3

IMHO you can implement sessions from Flask.

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

@app.route('/')
def index():
    if 'username' in session:
        print("Currents user's ID is %s" % session['id']
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        session['email'] = request.form['email']
        session['id'] = request.form['id']
        return redirect(url_for('index'))
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    session.pop('email', None)
    session.pop('id', None)
    return redirect(url_for('index'))

# set the secret key.  keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

See: http://flask.pocoo.org/docs/0.12/quickstart/#sessions

Comments

1

In flask 2.0.x user id is automaticly saved in session under _user_id, not sure how or where this changed, in the official flask docs it still uses g.user, but maybe its outdated? I couldnt get it to work for me.

The simplest way i could get it to check if a user was login in with if '_user_id' in sessions.keys(), the return value of session['_user_id'] is a string of User.id

Comments

0

Its better to use session for this. You can store the information is session then use it anywhere.

In your login function just store the value like: first import the session from flask.Then use like this.

session['username'] = login_form.username.data

then use it like {{ session['username'] }} in your template.

1 Comment

Is this recommended for flask security because it takes care of all of the user login management. What I don’t want to do is build functionality that already exists.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.