I'm trying to use enter link description here. If I use their minimal example, everything works fine but in my actual application, I use Flask-Session myself. Now the Flask-MonitoringDashboard also uses Flask-Session to store a session cookie and indicate if the user is logged in or not.
Here's a working example that also set's the secret key:
from flask import Flask, session
import flask_monitoringdashboard as dashboard
from flask_session import Session
class Config:
SECRET_KEY = "top-sercet!"
app = Flask(__name__)
app.config.from_object(Config)
dashboard.config.init_from(file='/home/pascal/test/dashboard_minimal/config.cfg')
dashboard.bind(app)
sess = Session()
#sess.init_app(app)
@app.route('/')
def index():
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True)
Note: I use absolute paths just to be sure.
Also here's config.cfg (copy pasted from their example)
[dashboard]
APP_VERSION=1.0
GIT=/home/pascal/test/dashboard_minimal/.git/
CUSTOM_LINK=dashboard
MONITOR_LEVEL=3
OUTLIER_DETECTION_CONSTANT=2.5
SAMPLING_PERIOD=20
ENABLE_LOGGING=True
[authentication]
USERNAME=admin
PASSWORD=admin
SECURITY_TOKEN=cc83733cb0af8b884ff6577086b87909
[database]
TABLE_PREFIX=fmd
DATABASE=sqlite://///home/pascal/test/dashboard_minimal/dashboard.db
[visualization]
TIMEZONE=Europe/Amsterdam
COLORS={'main':'[0,97,255]',
'static':'[255,153,0]'}
Now if you run flask --app main run and go to localhost:5000/dashboard you can login with admin and admin.
Now if we add Flask-Session to the app ourselves i.e. we uncomment sess.init_app(app) we get the error
RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
which is weird, since we did infact set it. The error is probably due to us not setting a interface. So we do that by changing the Config class to
class Config:
SECRET_KEY = "top-sercet!"
SESSION_TYPE = "memcached"
The error is gone but now we are in a infinite login loop when we try to login! This is, because Flask-MonitoringDashboard uses a @secure decorator where they read the session and check if the user is logged in but the value is never set! Here's what they do:
In [flask_monitoringdashboard/views/auth.py][3] we see the route that handles the login:
import flask
...
@blueprint.route('/login', methods=['GET', 'POST'])
def login():
"""
User for logging into the system. The POST-request checks whether the logging is valid.
If this is the case, the user is redirected to the main page.
:return:
"""
if flask.session.get(config.link + '_logged_in'):
return redirect(url_for(MAIN_PAGE))
if request.method == 'POST':
name = request.form['name']
password = request.form['password']
user = get_user(username=name, password=password)
if user is not None:
on_login(user=user)
return redirect(url_for(MAIN_PAGE))
return render_template('fmd_login.html',
blueprint_name=config.blueprint_name,
show_login_banner=config.show_login_banner,
show_login_footer=config.show_login_footer,
)
If we aren't logged in, we proceed to start authentication. In the on_login function they set the session:
from flask import session, redirect, url_for
def on_login(user):
session[config.link + '_user_id'] = user.id
session[config.link + '_logged_in'] = True
if user.is_admin:
session[config.link + '_admin'] = True
Once logged in, we get redirected return redirect(url_for(MAIN_PAGE)) which at some point calls the @secure decorator:
from flask import session, redirect, url_for
...
def secure(func):
"""
When the user is not logged into the system, the user is requested to the login page.
There are two types of user-modes:
- admin: Can be visited with this wrapper.
- guest: Can be visited with this wrapper.
:param func: the endpoint to be wrapped.
"""
@wraps(func)
def wrapper(*args, **kwargs):
if session and session.get(config.link + '_logged_in'):
return func(*args, **kwargs)
return redirect(url_for(config.blueprint_name + '.login'))
return wrapper
Not the different way of importing session. They have a name conflict in the first file, which is why they use flask.session.
Am I simply not initializing Flask-Session correctly or is there another issue? Any help is appreciated.