i am using flask-login to integrate session management in my flask app. But the remember me functionality doesn't work if i set the session_protection to strong , however, it works absolutely fine if it's set to basic .
user_loader:
@login_manager.user_loader
def load_user(email):
user = get_user_with_email(email)
if user:
return User(user.id, user.email, user.role_id, user.createtime, user.updatetime)
to fetch user from the database:
from psycopg2.extras import NamedTupleCursor
def get_user_with_email(email):
cursor = get_db().cursor(cursor_factory=NamedTupleCursor)
cursor.execute('SELECT * FROM users WHERE email = %s', (email,))
return cursor.fetchone()
and my user class:
class User(UserMixin):
def __init__(self, username, email, role_id, createtime, updatetime):
self.username = username
self.email = email
self.role_id = role_id
self.createtime = createtime
self.updatetime = updatetime
@property
def password(self):
raise AttributeError('password is not a readable property')
@password.setter
def password(self, password):
self._password = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self._password, password)
@property
def is_active(self):
"""All users are active"""
return True
@property
def is_anonymous(self):
"""Always return False, anonymous users aren't supported"""
return False
def get_id(self):
"""Return username for flask_login to use it as user id"""
return self.email
@property
def is_authenticated(self):
"""All users are authenticated"""
return True
def register(self, password):
self.password = password
# Todo: complete the registration logic
def __repr__(self):
return 'User(username={0}, email={1})'.format(self.username, self.email)
I am doing exactly what is mentioned in the documentation, but still the user logs out when the browser closes in case of strong protection. i am not sure what's going wrong.
I would appreciate any help, thanks !
You are not doing anything wrong, that is desired behavior when session protection is set to strong.
Edit:
Basically, when session protection is set (to basic or strong), after user logs in, session identifier is computed (based on users IP and users user-agent) and stored. And it is then computed upon each new request and checked with stored version.
After browser restart in order to load a user Flask-Login will check, beside the remember_me cookie, if the session id matches stored value. But since browser is restarted there won't be stored session id value and this test won't pass.So one of these two things will happen then.
If the protection is set to basic, session will be flagged as not fresh and user will be loaded from remember me cookie.
If the protection is set to strong the user won't be loaded and remember me cookie will be deleted.
It is good practice, if basic setting is used, to decorate view function that handles sensitive operations(such as password change) with fresh_login_required. As stated in the official docs:
flask_login.fresh_login_required(func) If you decorate a view with this, it will ensure that the current user's login is fresh - ie their session was not restored from a 'remember me' cookie. Sensitive operations, like changing a password or e-mail, should be protected with this, to impede the efforts of cookie thieves.
https://flask-login.readthedocs.io/en/latest/_modules/flask_login/utils.html#fresh_login_required
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.