flask keep a user logged in across browser sessions

44 Views Asked by At

I'm experiencing an issue with my Flask application where the user's logged-in state is not persisting after the browser is closed and reopened. I've tried configuring the session management and cookie settings, but the user is still being logged out when they return to the application.

I've set the SESSION_PERMANENT and PERMANENT_SESSION_LIFETIME configuration options to make the session permanent and set a long session lifetime. I've also set the SESSION_COOKIE_SECURE and SESSION_COOKIE_HTTPONLY flags to ensure secure cookie transmission and prevent client-side script access to cookies.

In the login route, after a successful login, I store the user's information in the session and set session.permanent = True to make the session permanent. When the user logs out, I clear the session data using session.clear().

However, despite these configurations, the user is still being logged out when they close and reopen the browser.

I've also tried removing the custom cookie handling and relying solely on the Flask session for managing user state, but the issue persists.

What could be causing this problem, and how can I ensure that the user remains logged in even after closing and reopening the browser?

Any help or suggestions would be greatly appreciated. Thank you!

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
    if 'email' in request.form and 'password' in request.form:
        email = request.form['email']
        password = request.form['password']
        user = User.query.filter_by(email=email).first()
        if user and check_password_hash(user.password, password):
            session['user_id'] = user.id
            session['email'] = email
            session['permission_level'] = user.permission_level
            session['user_language'] = user.preferred_language
            session.permanent = True  # Make the session permanent

            if user.permission_level == 'admin':
                return redirect(url_for('admin'))
            elif user.permission_level == 'affiliate':
                return redirect(url_for('ambassador_home'))
            elif user.permission_level == 'staff':
                return redirect(url_for('staff_home'))
        else:
            flash('Invalid credentials.', 'error')
    elif 'logout' in request.form:
        session.clear()  # Clear the session data
        flash('You have been logged out.', 'success')
        return redirect(url_for('login'))

if 'user_id' in session:
    user_id = session['user_id']
    user = User.query.get(user_id)
    if user:
        if user.permission_level == 'admin':
            return redirect(url_for('admin'))
        elif user.permission_level == 'affiliate':
            return redirect(url_for('ambassador_home'))
        elif user.permission_level == 'staff':
            return redirect(url_for('staff_home'))

user_language = session.get('user_language', 'en')  # Assign a default value if 'user_language' is not in the session
content = {
    'en': {
        'title': 'Login',
        'email_label': 'Email',
        'password_label': 'Password',
        'login_button': 'Login',
        'logout_button': 'Logout',
        'staff_message': 'You can now approve payments in the system by scanning customer QR codes.'
    },
    'es': {
        'title': 'Iniciar sesión',
        'email_label': 'Correo electrónico',
        'password_label': 'Contraseña',
        'login_button': 'Iniciar sesión',
        'logout_button': 'Cerrar sesión',
        'staff_message': 'Ahora puede aprobar pagos en el sistema escaneando los códigos QR de los clientes.'
    }
}

I also set these:

app = Flask(__name__)
app.config['SECRET_KEY'] = 'somethinghere'
app.config['SESSION_PERMANENT'] = True
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=3650)  # Set the session lifetime to 10 years
app.config['SESSION_COOKIE_SECURE'] = True  # Ensure cookies are only sent over HTTPS
app.config['SESSION_COOKIE_HTTPONLY'] = True 

EDIT:

I traced it to the chrome browser. But I haven't solved it. If I use Edge it's fine. What's more I found even stranger behaviour. I looked at my session cookie when being directed from one route to another. Here is the session cookie before redirection:

"<SecureCookieSession {'_permanent': True, 'email': '[email protected]', 'permission_level': 'admin', 'user_id': 9, 'user_language': 'en', 'user_qr_tracking_code': 'a124bca3-2727-4429-8c69-ab7f5950bfb8', 'rule_code': 'ef9ad7f7-44d9-4303-9111-a9532c89777d', 'content': {'venue_name': 'Sama Sky Lounge'}}>"

And here it is directly at the top of the other route:

"<SecureCookieSession {'_permanent': True, 'email': '[email protected]', 'permission_level': 'admin', 'user_id': 9, 'user_language': 'en'}>"

Some elements have just vanished but there were no python statements between these 2 printouts of the session variable. Then I ran it in Edge, and no problem. I have tried checking my chrome cookie settings, removing all plugins, and also resetting chrome experimental features.

Using Chrome Incognito works!

What could be causing this weird behaviour?

Here is my relevant app.config

app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=3650)  # Set the session lifetime to 10 years
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_PATH'] = '/'

And here are the routes with the session logging statements:

def landing_redirect(rule_code):
    qr_code = QRCode.query.filter_by(rule_code=rule_code).first()
    if qr_code:
        user_qr_tracking_code = generate_unique_code()
        session['user_qr_tracking_code'] = user_qr_tracking_code
        session['rule_code'] = rule_code
        content = {
            'venue_name': qr_code.venue_name
        }
        session['content'] = content
        session.permanent=True
        log_it(session)
        return redirect(url_for('make_customer_qr'))
    else:
        return "Invalid QR code", 404

@app.route('/make_customer_qr', methods=['GET', 'POST'])
def make_customer_qr():
    log_it(session)
    etc....
0

There are 0 best solutions below