I have a nasty issue which I have been fighting relentlessly for the past 3 days, but its not tilting.
In my Flask application the current_user which comes from Flask-login is not updated across requests when the application is deployed to AWS EBS.
When running the application locally its updated fine.
The issue happens on AWS EBS which also uses Nginx for proxy
User A logs into the application
User B from another devices access the application and is automatically logged in as user A
I have checked the sessions and it creates unique session and I can see them in the database (also have logs)
But the problem is the current_user is not updated so basically the whole app treats User B as User A
Any ideas what could cause that please?
This is my user login page where the issue happens
@user_bp.route('/')@user_bp.route('/signin', methods=['GET','POST'])def signin(): try: logger.debug(f"Signin accessed by current_user is_authenticated= {current_user.is_authenticated}") logger.debug(f"Session initial= {session}") if current_user.is_authenticated: logger.debug("User already authenticated, redirecting to dashboard") return redirect(url_for('user_bp.dashboard')) form = LoginForm() if form.validate_on_submit(): logger.debug(f"Form submission received for username: {form.username.data}") user = User.query.filter_by(email=form.username.data).first() if user is None or not user.check_password(form.password.data): logger.warning(f"Authentication failed for email: {form.username.data}") flash('Invalid username or password') return redirect(url_for('user_bp.signin')) login_user(user) logger.debug(f"Session after login= {session}") logger.debug(f"User logged in successfully, user id: {user.id}") next_page = request.args.get('next') if not next_page or url_parse(next_page).netloc != '': next_page = url_for('user_bp.dashboard') logger.debug(f"Redirecting to {next_page}") return redirect(next_page) else: logger.debug("Form failed to validate on submit.") for field, errors in form.errors.items(): for error in errors: logger.error(f"Error in the {getattr(form, field).label.text} field - {error}") logger.debug(f"Form CSRF Token: {form.csrf_token.data}") logger.debug(f"Session CSRF Token: {session.get('_csrf_token')}") return render_template('signin.html', form=form)
Configs
SECRET_KEY = os.environ.get('SECRET_KEY') if not SECRET_KEY: raise ValueError("No SECRET_KEY set for Flask application") CACHE_TYPE = "SimpleCache" SESSION_TYPE = 'sqlalchemy' SESSION_SQLALCHEMY_TABLE = 'sessions' SESSION_PERMANENT = True SESSION_USE_SIGNER = True PERMANENT_SESSION_LIFETIME = timedelta(minutes=60) SESSION_COOKIE_NAME = 'myapp_session' SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SAMESITE = 'None' SESSION_COOKIE_SECURE = True REMEMBER_COOKIE_DURATION = timedelta(days=7) SERVER_NAME = os.environ.get('SERVER_NAME')
The main.py file
app = Flask(__name__)app.config.from_object(Config)db = SQLAlchemy(app)cache = Cache(app)migrate = Migrate(app, db)login = LoginManager(app)login.login_view = 'user_bp.signin'configure_logging()inject_theme(app)app.config['SESSION_SQLALCHEMY'] = dbsess = Session(app)# Generate a unique request ID for each request@app.before_requestdef before_request(): g.request_id = str(uuid.uuid4())@app.after_requestdef add_header(response): response.headers["Cache-Control"] = "no-store, max-age=0" return response
The user loader
@login.user_loaderdef load_user(id): return User.query.get(int(id))
Also you can see the logs, when User A(green) logs in succesfully, then User B(yellow) goes to the sign in page and it decides that he is authenticated and logged in as User A
Also here is the nginx config regarding headers
location / {proxy_pass http://127.0.0.1:8000;proxy_http_version 1.1;proxy_set_header Connection $connection_upgrade;proxy_set_header Upgrade $http_upgrade;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }