





















































(For more resources related to this topic, see here.)
We will work from the app.py file from the sched directory and the models.py file.
from flask import session
# ... in a request ...
session['spam'] = 'eggs'
# ... in another request ...
spam = session.get('spam') # 'eggs'
Flask
Flask-Login
Flask-Script
Flask-SQLAlchemy
WTForms
$ pip install -r requirements.txt
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)
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.
@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'))
from flask.ext.login import login_required
@app.route('/appointments/')
@login_required
def appointment_list():
# ...
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.
Flask's session supports display of messages and protection against request forgery.
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 %}
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/.
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.
Further resources on this subject: