4 min read

(For more resources related to this topic, see here.)

Getting ready

We will work from the app.py file from the sched directory and the models.py file.

How to do it…

  1. Flask provides a session object, which behaves like a Python dictionary, and persists automatically across requests. You can, in your Flask application code:

    from flask import session
    # ... in a request ...
    session['spam'] = 'eggs'
    # ... in another request ...
    spam = session.get('spam') # 'eggs'

  2. Flask-Login provides a simple means to track a user in Flask’s session. Update requirements.txt:

    Flask
    Flask-Login
    Flask-Script
    Flask-SQLAlchemy
    WTForms

  3. Then:

    $ pip install -r requirements.txt

  4. We can then load Flask-Login into sched‘s request handling, in app.py:

    from flask.ext.login import LoginManager, current_user
    from flask.ext.login import login_user, logout_user
    from sched.models import User
    # Use Flask-Login to track current user in Flask's session.
    login_manager = LoginManager()
    login_manager.setup_app(app)
    login_manager.login_view = 'login'
    @login_manager.user_loader
    def load_user(user_id):
    """Flask-Login hook to load a User instance from ID."""
    return db.session.query(User).get(user_id)

  5. Flask-Login requires four methods on the User object, inside class User in models.py:

    def get_id(self):
    return str(self.id)
    def is_active(self):
    return True
    def is_anonymous(self):
    return False
    def is_authenticated(self):
    return True

    Flask-Login provides a UserMixin (flask.ext.login.UserMixin) if you prefer to use its default implementation.

  6. We then provide routes to log the user in when authenticated and log out. In app.py:

    @app.route('/login/', methods=['GET', 'POST']) def login(): if current_user.is_authenticated(): return redirect(url_for('appointment_list')) form = LoginForm(request.form) error = None if request.method == 'POST' and form.validate(): email = form.username.data.lower().strip() password = form.password.data.lower().strip() user, authenticated = User.authenticate(db.session.query, email, password) if authenticated: login_user(user) return redirect(url_for('appointment_list')) else: error = 'Incorrect username or password.' return render_template('user/login.html', form=form, error=error) @app.route('/logout/') def logout(): logout_user() return redirect(url_for('login'))

  7. We then decorate every view function that requires a valid user, in app.py:

    from flask.ext.login import login_required
    @app.route('/appointments/')
    @login_required
    def appointment_list():
    # ...

How it works…

On login_user, Flask-Login gets the user object’s ID from User.get_id and stores it in Flask’s session. Flask-Login then sets a before_request handler to load the user instance into the current_user object, using the load_user hook we provide. The logout_user function then removes the relevant bits from the session.

If no user is logged in, then current_user will provide an anonymous user object which results in current_user.is_anonymous() returning True and current_user. is_authenticated() returning False, which allows application and template code to base logic on whether the user is valid. (Flask-Login puts current_user into all template contexts.) You can use User.is_active to make user accounts invalid without actually deleting them, by returning False as appropriate.

View functions decorated with login_required will redirect the user to the login view if the current user is not authenticated, without calling the decorated function.

There’s more…

Flask’s session supports display of messages and protection against request forgery.

Flashing messages

When you want to display a simple message to indicate a successful operation or a failure quickly, you can use Flask’s flash messaging, which loads the message into the session until it is retrieved. In application code, inside request handling code:

from flask import flash
flash('Sucessfully did that thing.', 'success')

In template code, where you can use the ‘success‘ category for conditional display:

{% for cat, m in get_flashed_messages(with_categories=true) %}
<div class="alert">{{ m }}</div>
{% endfor %}

Cross-site request forgery protection

Malicious web code will attempt to forge data-altering requests for other web services. To protect against forgery, you can load a randomized token into the session and into the HTML form, and reject the request when the two do not match. This is provided in the Flask-SeaSurf extension, pythonhosted.org/Flask-SeaSurf/ or the Flask-WTF extension (which integrates WTForms), pythonhosted.org/Flask-ETF/.

Summary

This article explained how to keep users logged in for on-going requests after authentication. It shed light on how Flask provides a session object, which behaves like a Python dictionary, and persists automatically across requests. It also spoke about coding in Flask application. We got acquainted with flashing messages and cross-site request forgery protection.

Resources for Article:


Further resources on this subject:


Packt

Share
Published by
Packt

Recent Posts

Top life hacks for prepping for your IT certification exam

I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…

3 years ago

Learn Transformers for Natural Language Processing with Denis Rothman

Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…

3 years ago

Learning Essential Linux Commands for Navigating the Shell Effectively

Once we learn how to deploy an Ubuntu server, how to manage users, and how…

3 years ago

Clean Coding in Python with Mariano Anaya

Key-takeaways:   Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…

3 years ago

Exploring Forms in Angular – types, benefits and differences   

While developing a web application, or setting dynamic pages and meta tags we need to deal with…

3 years ago

Gain Practical Expertise with the Latest Edition of Software Architecture with C# 9 and .NET 5

Software architecture is one of the most discussed topics in the software industry today, and…

3 years ago